目录
一、函数型接口
1.1 概念
- 接口中只有一个抽象方法,可以有默认的方法和其它的方法
- @FunctionalInterface 可用来检查是否是函数型接口
1.2 四个函数型接口
1.2.1 Supplier 供给型接口
- 只提供一个返回值、无参的方法
package qf22020311_supplier;
import java.util.function.Supplier;
/**
* @author 18480
* 函数型接口supplier,只有一个抽象方法、只提供一个返回值功能
*/
public class MyTest01 {
public static void main(String[] args) {
System.out.println(getMax(() -> {
int[] arr = {1, 4, 10, 2};
int max = arr[0];
for (int i = 1; i < arr.length; i++) {
if (max < arr[i]) {
max = arr[i];
}
}
return max;
}));
}
public static Integer getMax(Supplier<Integer> a) {
return a.get();
}
}
1.2.2 Consumer 消费型接口
- 图
- 代码演示
package qf22020311_consumer;
import java.util.function.Consumer;
/**
* 消费型接口,其中抽象方法有一个参数无返回值
*/
public class MyTest {
public static void main(String[] args) {
get("abcb", s1 -> System.out.print(s1.charAt(1)), s2 -> System.out.println(s2.charAt(3)));
}
public static void get(String str, Consumer<String> con1, Consumer<String> con2) {
//意思是con1连接con2对str执行操作
con1.andThen(con2).accept(str);
}
}
1.2.3 Predicate 断言型接口
- 图
- 代码演示
package qf22020311_predicate;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;
/**
* Predicate 断言型接口
*
* @author 18480
*/
public class Demo01 {
public static void main(String[] args) {
String[] arr1 = {"迪丽热巴", "古丽哪吒", "杨幂"};
System.out.println(getList(arr1, (String s1) -> s1.length() >= 4, (String s2) -> s2.contains("古")));
}
public static List<String> getList(String[] arr1, Predicate<String> pre1, Predicate<String> pre2) {
List<String> list = new ArrayList<>();
//使用and断言方法,作为&&两者均成立则为真
for (String s : arr1) {
if (pre1.and(pre2).test(s)) {
list.add(s);
}
}
return list;
}
}
1.2.4 Function 函数型转换接口
package qf22020311_function;
import java.util.function.Function;
/**
* 函数型转换接口
*/
public class Test01 {
public static void main(String[] args) {
//integer类型转换成String类型,再转换成Double类型
System.out.println(cast(10, (Integer a) -> String.valueOf(a), (String s) -> Double.parseDouble(s)));
}
public static double cast(Integer n, Function<Integer, String> fun1, Function<String, Double> fun2) {
//返回转换最后的类型
return fun1.andThen(fun2).apply(n);
}
}
二、stream流
2.1 概念
- stream是一个接口,主要对数据进行过滤
- stream提供了两类方法:A. 延迟方法是调用方法之后返回的仍然是stream对象 B.总结方法是调用方法之后返回的不是stream对象
2.2 stream对象的获取
-
图
-
单列集合调用返回获取stream对象
List<String> list = new ArrayList<>();
Stream<String> stream = list.stream();
- stream.of() 获取stream对象
Stream<String> stream = Stream.of("a","b","1");
2.3 常用的方法
- 图
2.4 方法案例
package qf22020311_stream;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
/**
* @author 18480
*/
public class Demo01 {
@Test
public void test01() {
List<String> list = new ArrayList<>();
list.add("1");
list.add("b");
list.add("c");
Stream<String> stream = list.stream();
//filter过滤器中传入的是断言函数接口,forEach循环中传入的是消费者函数接口
stream.filter(((String s) -> s.equals("b"))).forEach((String s) -> System.out.println(s));
}
@Test
public void test02() {
List<String> list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("1");
Stream<String> stream = list.stream();
//count()统计元素中的个数
System.out.println(stream.count());
}
@Test
public void test03() {
Stream<String> stream = Stream.of("a", "b", "1");
Stream<String> limit = stream.limit(2);
//limit截取0-2的下标的个数,取不到2
limit.forEach((String s) -> System.out.println(s));
}
@Test
public void test04() {
Stream<String> stream = Stream.of("1", "3", "2");
//Consumer作为传入消费者接口,做数据类型转换
stream.forEach((String s) -> System.out.println(Double.parseDouble(s)));
}
}
三、注解
3.1 注释与注解的区别
- 注释:用于解释说明代码,给开发人员观看
- 注解:用于解释说明代码,主要提供给jvm观看
- 定义:注解 (Annotation),也叫元数据,一种代码级别的说明
- 注解作用:编写文档、代码分析、编译检查
- 注解接口里的都是属性
3.2 jdk提供注解
- @Override 用于检查是否重写的方法
- @Deprecated 标注该方法过时
- @SuppressWarnings/("all"全部) 压制黄色的警告线
3.3 自定义注解
- 定义:B.public @interface SuppressWarnings {}
- 本质就是一个接口
- 注解中的属性的返回值类型:(四类八种)
- A.基本数据类型
- B.String类型
- C.枚举类型
- D.注解类型
- E.以上类型的数组类型
- 代码演示
public @interface MyAnno {
int num1();
//String[] num2();
String num2();
MyEnum num3();
//注解
Anno MY_ANNO();
}
3.4 元注解
- 在自定义注解时可以使用元注解
- @Target 主要用于来表示注解作用的位置
TYPE 表示在类上面可以使用
FIELD 表示在属性上可以使用
METHOD 表示在方法上可以使用 - @Retention 主要用于注解是否可以被识别
RUNTIME 表示项目在运行的时候 jvm可以识别这个注解 - @Inherited 用于表示注解是否继续被子类继承的使用
- @Documented 用于标注是否在api文档上显示这个注解
3.5 案例应用
- 问题:使用注解向注解接口中注入属性值,利用反射获取属性值,然后利用反射根据属性值创建对象并调用方法
- 步骤1:自定义注解,添加两个属性
package qf22020311_annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author 18480
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnno {
String classname();
String method();
}
- 步骤2:编写一个实体类
package qf22020311_annotation;
public class Student {
private Student() {
}
public void get() {
System.out.println("获取到了");
}
}
- 步骤3:测试类
package qf22020311_annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* TODO 自定义注解
*
* @author 18480
*/
@MyAnno(classname = "qf22020311_annotation.Student", method = "get")
public class Demo01 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
//利用本身来来获取Class对象,调用方法获取MyAnno对象
MyAnno cal = Demo01.class.getAnnotation(MyAnno.class);
//获取注解接口属性值
String classname = cal.classname();
String method = cal.method();
//加载Class
Class<?> aClass = Class.forName(classname);
//创建构造方法
Constructor<?> cons = aClass.getDeclaredConstructor();
//暴力对私有的构造创建
cons.setAccessible(true);
//实例化对象
Object o = cons.newInstance();
//获取操作方法的方法对象
Method method1 = aClass.getMethod(method);
//调用方法
method1.invoke(o);
}
}