Consumer<T> : 消费型接口 -- 有去无回
void accept(T t);
Supplier<T> : 供给型接口
T get();
Function<T,R>: 函数型接口
R apply(T t)
Predicate<T>: 断言型接口
boolean test(T t);
四大 接口 示例:
?// 消费型 , 有去无回 ?@Test ? ? ?public void test(){ ? ? ? ? ?happy(300.09,x-> System.out.println(x)); ? ? } ?? ? ? ?public void happy(double money,Consumer<Double> consumer){ ? ? ? ? ?consumer.accept(money); ? ? } ?// 供给型, 主要生产对象 ?// 需求 : 生产指定个数的整数 ,放入集合中 ? @Test ? ? ?public void test(){ ? ? ? ? ?// 随机生产5个随机数 ? ? ? ? change(5,()->Double.valueOf(Math.random()*100).intValue()).forEach(System.out::println); ? ? } ?? ? ? public List<Integer> change(Integer num, Supplier<Integer> sup){ ? ? ? ? List<Integer> list = new ArrayList<>(); ? ? ? ? ?for(int i=0;i<num;i++){ ? ? ? ? ? ? ?list.add(sup.get()); ? ? ? ? } ?? ? ? ? ? ?return list; ? ? } ?//函数型接口 ?// 需求: 处理字符串 ? ? @Test ? ? ?public void test(){ ? ? ? ? ?// 随机生产5个随机数 ? ? ? ? ?String str = change("abc1234",s->s.toUpperCase()); ? ? ? ? ?System.out.println(str); ? ? } ?? ? ? public String change(String str, Function<String,String> fun){ ? ? ? ? ?return fun.apply(str); ? ? } ?//断言型接口 ?//将满足条件的字符串放入集合 ?@Test ? ? ?public void test(){ ? ? ? ? ?// 找出集合中 字符长度大于3的 ? ? ? ? ?List<String> strs=Arrays.asList("a","ab34","abc","abcd","a1","bcd"); ? ? ? ? ?List<String> str = change(strs,s->s.length()>3); ? ? ? ? ?System.out.println(str); ? ? } ?? ? ? public List<String> change(List<String> list, Predicate<String> pre){ ? ? ? ? List<String> strList = new ArrayList<>(); ? ? ? ? for(String str:list){ ? ? ? ? ? ? if(pre.test(str)){ ? ? ? ? ? ? ? ? strList.add(str); ? ? ? ? ? ? } ? ? ? ? } ? ? ? ? ?return strList; ? ? }
如果以上不够用 还有其他的一些接口
方法引用: 若lambda 体中的内容 有方法已经实现了, 我们可以使用"方法的引用"
(可以理解为方法引用是Laambda表达式的另外一种表现形式)
主要有三种语法格式:
(Lambda体 中调用方法的参数列表与返回值类型, 要与 函数式接口中 抽象方法的参数列表与返回值类型保持一致)
对象::实例方法名
类::静态方法名
类::实例方法名:若Lambda 参数列表中的第一个参数是 实例方法的调用者,而第二个参数是实例方法的参数时, 可以使用 类名::实例方法,, 返回值也得一致
对象::实例方法名
示例: System.out::println
?@Test ?public void test(){ ?Consumer<String> consumer = x->System.out.println(x); ?consumer.accept("你好!!!"); ? // 打印输出 ?? ? // 功能与上面等价,但是要求 void println(String s)与接口 中的void accept(T t) 参数类型与返回值类型一致 ? Consumer<String> consumer2 = System.out::println; ? ? consumer2.accept("你好!!!22222"); ? // 打印输出 ?} ?? ?? ?? ?? ?@Test ? public void test2(){ ? ? ? Emp emp = new Emp("李四77777",3000,40); ?? ? ? ? Supplier<String> consumer = ()->emp.getName(); ? ? ? System.out.println(consumer.get()); ?? ? ? ? Supplier<String> c = emp::getName; ? ? ? System.out.println(c.get()); ? }
类::静态方法名
?@Test ?public void test3(){ ?? ? Supplier<Double> con = ()->Math.random(); ? System.out.println(con.get()); ?? ? Supplier<Double> con2 = Math::random; ? System.out.println(con2.get()); ?} ?? ?@Test ? public void test3(){ ?? ? ? ? Comparator<Integer> com = (x,y)->Integer.compare(x,y); ? ? ? System.out.println(com.compare(4,5)); ?? ? ? ? Comparator<Integer> com2 = Integer::compare; ? ? ? System.out.println(com2.compare(4,5)); ? }
类::实例方法
?@Test ?public void test6(){ ?? ? BiPredicate<String,String> pre = (x,y)->x.equals(y); ? // 第一个参数是调用者, 第二个为方法的参数 ,才可以这样写 ? BiPredicate<String,String> pre2 = String::equals; ?}
语法格式: 类名::new
需要调用的构造器的参数列表 要与函数式接口中 抽象方法的参数列表保持一致
?? ?//实体类 ?@NoArgsConstructor ?@AllArgsConstructor ?@Data ?@ToString ?public class Emp { ? private String name; ? private double salary; ? private int age; ?? ? public Emp(String name){ ? ? ? this.name = name; ? } ?} ?? ?@Test ?public void test6(){ ?? ? Supplier<Emp> sup = ()->new Emp(); ? Supplier<Emp> e2 = Emp::new; ? // 调用 无参构造, 因为 supplier中的接口 T accept() 就是无参的 ?? ? Function<String,Emp> func = x->new Emp(x); ? Function<String,Emp> func2 = Emp::new; //调用 带String参数的构造方法, 因为Function接口中 R apply(T t) ? System.out.println(func2.apply("lisi").getName());// 输出 lisi ?} ?? ??
语法格式: Type[]::new
@Test public void test7(){ Function<Integer,String[]> fun = x->new String[x]; String[] abc = fun.apply(10); Function<Integer,String[]> fun2 = String[]::new; }