目录
3.1、Supplier [səˈplaɪə(r)] Supplier接口
3.3、Predicate [ˈpredɪkət , ˈpredɪkeɪt] 接口
1、函数式接口概述
- 函数式接口: 有且仅有一个抽象方法的接口。
- Java中的函数式编程体现就是Lambda表达式。
- 所以函数式接口即可以适用于Lambda使用的接口。
如何检测一个接口是不是函数式接口?
@FunctionalInterface
- 放在接口定义的上方:如果接口是函数式接口,编译通过;如果不是,编译失败。
package com.test8;@FunctionalInterfacepublic interface Inter { void show();}
package com.test8;public class Demo { public static void main(String[] args) { Inter i=()-> System.out.println("Hello world!"); i.show(); }}
注意:自定义函数式接口时,@FunctionalInterface是可选的,就算不写这个注解,只要保证满足函数式接口定义的条件,也照样是函数式接口
2、函数式接口做为方法的参数
如果方法的参数是一个函数式接口,可以使用Lambda表达式作为参数传递
package com.test9;public class Demo { public static void main(String[] args) { //匿名内部类 startThread(new Runnable() { @Override public void run() { System.out.println(Thread.currentThread().getName()+"线程启动"); } }); //Lambda表达式 startThread(()-> System.out.println(Thread.currentThread().getName()+"线程启动")); } private static void startThread(Runnable r){ Thread t=new Thread(r); t.start(); }}
3、函数式接口作为方法的返回值
如果方法的返回值是一个函数式接口,可以使用Lambda表达式作为结果返回
package com.test10;import java.util.ArrayList;import java.util.Collections;import java.util.Comparator;public class Demo { public static void main(String[] args) { ArrayList array=new ArrayList(); array.add("aa"); array.add("b"); array.add("cccc"); array.add("ddd"); System.out.println("排序前:"+array); Collections.sort(array);//自然排序 System.out.println("自然排序后:"+array); Collections.sort(array,getComparator()); System.out.println("指定比较器排序后:"+array); } private static Comparator getComparator(){ //匿名内部类方式实现// Comparator comp=new Comparator() {// @Override// public int compare(String s1, String s2) {// return s1.length()-s2.length();// }//// };// return comp; //Lambda表达式// return (String s1,String s2)->{// return s1.length()-s2.length();// }; return (s1,s2)->s1.length()-s2.length(); }}
3、常用的函数式接口
Java8在java.util.function包下预定义了大量的函数数式接口供我们使用
- Supplier接口
- Consumer接口
- Predicate接口
- Function接口
3.1、Supplier [səˈplaɪə(r)] Supplier接口
Supplier:包含一个无参的方法
- T get():获得结果
- 该方法不需要参数,它会按照某种实现逻辑(由Lambda表达式实现)返回一个数据。
- Supplier接口也称为生产型接口,如果我们指定了接口的泛型是什么类型,那么接口中的get方法就会生产什么类型的数据供我们使用
案例一:
package com.test11;import java.util.function.Supplier;public class Demo { public static void main(String[] args) {// String s=getString(()->{// return "唐青枫";// }); String s=getString(()->"唐青枫"); System.out.println(s); Integer i=getInteger(()->10); System.out.println(i); } private static String getString(Supplier sup){ return sup.get(); } private static Integer getInteger(Supplier sup){ return sup.get(); }}
案例二:
package com.test10;import java.util.function.Supplier;public class Test { public static void main(String[] args) { int[] arr={1,9,2,7,5}; int maxValue=getMax(()->{ int max=arr[0]; for(int i=1;imax){ max=arr[i]; } } return max; }); System.out.println(maxValue); } private static int getMax(Supplier sup){ return sup.get(); }}
3.2、Consumer接口
Consumer:包含两个方法
- void accept(T t):对给定的参数执行此操作。
- default Consumer andThen(Consumer after):返回一个组合的Consumer,依次执行操作,然后执行after操作。
- Consumer接口也称为消费型接口,它消费的数据的数据类型由泛型指定
案例一:
package com.test10;import java.util.function.Consumer;public class ConsumerDemo { public static void main(String[] args) { //Lambda表达式 operatorString("唐青枫",(String name)->{ System.out.println(name); }); //Lambda表达式 operatorString("唐青枫",name-> System.out.println(name)); //方法引用 operatorString("唐青枫", System.out::println); //Lambda表达式 operatorString("唐青枫",(String name)->{ String s=new StringBuilder(name).reverse().toString(); System.out.println(s); }); System.out.println("****************************"); //Lambda表达式 operatorString("曲无忆",name-> System.out.println(name),name-> System.out.println(new StringBuilder(name).reverse().toString())); } //消费一个字符串数据 private static void operatorString(String name, Consumer con){ con.accept(name); } //用不同的方消费同一个字符串数据两次 private static void operatorString(String name,Consumer con1,Consumer con2){// con1.accept(name);// con2.accept(name); //上两行代码等价于 con1.andThen(con2).accept(name); }}
案例二:
package com.test10;import java.util.function.Consumer;public class ConsumerTest { public static void main(String[] args) { String[] arr={"唐青枫,20","曲无忆,21","离玉堂,22","叶知秋,23"}; printInfo(arr, (String str)->{ String name=str.split(",")[0]; System.out.print("姓名:"+name); }, (String str)->{ int age=Integer.parseInt(str.split(",")[1]); System.out.println(",年龄:"+age); }); } private static void printInfo(String[] arr, Consumer con1, Consumer con2){ for(int i=0;i
3.3、Predicate [ˈpredɪkət , ˈpredɪkeɪt] 接口
Predicate:常用的四个方法:
- boolean test(T t):对给定的参数进行判断(判断逻辑由Lambda表达式实现),返回一个布尔值。
- default Predicate
negate():返回一个逻辑的否定,对应逻辑非。 - default Predicate
and(Predicate other):返回一个组合判断,对应短路与。 - default Predicate
or(Predicate other):返回一个组合判断,对应短路或。 - Predicate接口通常用于判断参数是否满足指定的条件
negate、test案例:
package com.test12;import java.util.function.Predicate;public class Demo { public static void main(String[] args) { //Lambda表达式// boolean b=checkString("Hello",(String str)->{// return str.length()>8;// }); boolean b=checkString("Hello",str->str.length()>8); System.out.println(b); System.out.println("****************************"); b=checkString1("Hello",str->str.length()>8); System.out.println(b); } private static boolean checkString(String str, Predicate pre){ return pre.test(str); } private static boolean checkString1(String str,Predicate pre){// return !pre.test(str); //上一句等价于 return pre.negate().test(str); }}
and、or案例:
package com.test12;import java.util.function.Predicate;public class Demo1 { public static void main(String[] args) { boolean b1=checkString("hello",s->s.length()>8,s->s.length()<15); boolean b2=checkString("helloworld",s->s.length()>8,s->s.length()<15); System.out.println(b1); System.out.println(b2); } private static boolean checkString(String str, Predicate pre1, Predicate pre2){// boolean b1=pre1.test(str);// boolean b2=pre2.test(str);// boolean b=b1 && b2;// return b; //上述等价于 return pre1.and(pre2).test(str);//判断两个条件和 //对应的有// return pre1.or(pre2).test(str);//判断两个条件或 }}
案例:筛选满足条件的数据
姓名长度>2且年龄>20
package com.test13;import java.util.ArrayList;import java.util.function.Predicate;public class Demo { public static void main(String[] args) { String[] arr={"唐青枫,20","慕晴,21","曲无忆,22","孔雀,23","离玉堂,25"}; //姓名长度>2且年龄>20 ArrayList arrayList=myFilter(arr,str->str.split(",")[0].length()>2, str->Integer.parseInt(str.split(",")[1])>20); for(String str:arrayList){ System.out.println(str); } } private static ArrayList myFilter(String[] arr, Predicate pre1, Predicate pre2){ ArrayList arrayList=new ArrayList(); for(int i=0;i
3.4、Function接口
Function
:常用的两个方法:
- R apply(T t):将此函数应用于给定的参数。
- default
Function andThen(Function after):返回一个组合函数,首先将该函数应用于输入,然后将after函数应用于结果。 - Function
:接口通常用于对参数进行处理,转换(处理逻辑由Lambda表达式实现),然后返回一个新的值
package com.test14;import java.util.function.Function;public class Demo { public static void main(String[] args) { convert("666",(s)->Integer.parseInt(s)); convert(666,i->String.valueOf(i)); convert("666",s->Integer.parseInt(s),i->String.valueOf(i)); } private static void convert(String s, Function fun){ int i=fun.apply(s); System.out.println(i); } private static void convert(Integer i,Function fun){ String s=fun.apply(i); System.out.println(s); } private static void convert(String s,Function fun1,Function fun2){// int i=fun1.apply(s);// String str=fun2.apply(i); String str=fun1.andThen(fun2).apply(s); System.out.println(str); }}
来源地址:https://blog.csdn.net/huangtenglong/article/details/131156175