函数式接口
- 函数式接口
- 函数式接口概述
- 函数式接口作为方法的参数
- 函数式接口作为方法的返回值
- 常用的函数式接口
- Supplier接口
- Comsumer接口
- Predicate接口
- Function接口
函数式接口
函数式接口概述
有且仅有一个抽象方法的接口
是lambda表达式的前提
需要注意的是
- 默认方法不是抽象方法,因为它们已经实现了。
- 重写了超类Object类中任意一个public方法的方法并不算接口中的抽象方法。
Java中的函数式编程体现的就是Lambda表达式,所以函数式接口就是可以适用于Lambda使用的接口。只有确保接口中有且仅有一个抽象方法,Java中的lambda才能顺利地进行推导
public interface MyInterface{void show();
}
public class MyInterfaceDemo{public static void main(String[] args){MyInterface my=()->System.out.println("函数式接口");my.show();}
}
如何检测一个接口是不是函数式接口?
- @FunctionalInterface
- 放在接口定义的上方:如果是函数式接口编译通过,不是则编译失败
注意
- 自己定义函数式接口的时候,**@FunctionalInterface**是可选的,只要满足函数式接口的条件,不写也是,但是建议加上这个注解。
函数式接口作为方法的参数
需求
- 定义一个类(RunnableDemo),在类中提供两个方法
- 一个方法是:startThread(Runnable r) 方法参数Runnable是一个函数式接口
- 一个方法是主方法,在主方法中调用startThread方法
public class RunnableDemo{public static void main(String[] args){//匿名内部类的方式startThread(new Runnable(){@Overridepublic 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();new Thread(r).start();}
}
如果方法的参数是一个函数式接口,可以使用Lambda表达式作为参数传递
- startThread(()->System.out.println(Thread.currentThread().getName()+“线程启动了!”));
函数式接口作为方法的返回值
需求
- 定义一个类(ComparatorDemo)在类中提供两个方法
- 一个方法是:Comparator<String>getComparator() 方法的返回值是Comparator是一个函数式接口
- 一个方法是主方法,在主方法中 调用getComparator方法
public class ComparatorDemo{public static void main(String[] args){//构造使用场景//定义集合存储字符串元素ArrayList<String> array=new ArrayList<String> ();array.add("c");array.add("aaa");array.add("bb");System.out.println("排序前:"+array);Collections.sort(array, getcomparator()) ;System.out.println("排序后:"+array);}public static Comparator<String> getComparator(){//匿名内部类的方式实现
// Comparator<String> comp=new Comparator<String>(){
// @Override
// public int compare(String s1,String s2){
// return s1.length()-s2.length();
// }
// };
// return comp;// return new Comparator<String>(){
// @Override
// public int compare(String s1,String s2){
// return s1.length()-s2.length();
// }//lambda表达式
// return (String s1,String s2)->{
// return s1.length()-s2.length();
// };
// }return (s1,s2)-> return s1.length()-s2.length();}}
}
如果方法的返回值是一个函数式接口,可以使用lambda表达式作为结果返回
常用的函数式接口
Supplier接口
Supplier:包含一个无参的方法
- T get():获得结果
- 该方法不需要参数,它会按照某种实现逻辑(由Lambda表达式实现)返回一个数据
- supplier接口也被称为生产型接口,如果我们指定了接口的泛型是什么类型,那么接口中的get方法就会生产什么类
型的数据供我们使用
public class SupplierDemo{public static void main(String[] args){
// String s=getString(()->{
// return "伦伦";
// });String s=getString(()->"伦伦");System.out.println(s);Integer i=getInteger(()->30);System.out.println(i);}//定义一个方法,返回一个字符串数据private static String getString(Supplier<String> sup){return sup.get();}//定义一个方法返回整数数据private static Integer getInteger(Supplier<Integer> sup){return sup.get();}
}
Comsumer接口
Consumer:包含两个方法
- void accept(T t):对给定的参数执行此操作
- default Consumer andThen(Consumer after): 返回一个组合的Consumer,依次执行此操作,然后执行after操作
public class ConsumerDemo{public static void main(String[] args){
// operatorString("伦伦",(String s)->{
// System.out.println(s);
// });operatorString("伦伦",s->System.out.println(s));//方法引用改进operatorString("伦伦",System.out::println);operatorString("Y伦伦",(s)->{System.out.println(new StringBuilder(s).reverse().toString());});//优化operatorString("Y伦伦",s->System.out.println(new StringBuilder(s).reverse().toString()));System.out.println("----------");operatorString("Y伦伦",s->System.out.println(s),s->System.out.println(new StringBuilder(s).reverse().toString()));}//定义一个方法消费字符串数据private static void operatorString(String name,Consumer<String> con){con.accept(name);}//定义一个方法,用不同的方式消耗同一个字符串两次private static void operatorString(String name,Consumer<String> con1,Consumer<String> con2){
// con1.accept(name);
// coo2.accept(name);//改进con1.andThen(con2).accept(name);}
}
Predicate接口
Predicate:常用的四个方法
- boolean test(T t):对给定的参数进行判断(判断逻辑由Lambda表达式实现),返回一个布尔值
- default Predicatenegate(): 返回一个逻辑的否定,对应逻辑非
- defaultPredicateand(Predicateother): 返回一个组合判断,对应短路与
- default Predicate or(Predicate other): 返回一个组合判断,对应短路或
- Predicate接口通常用于判断参数是否满足指定的条件
public class PredicateDemo01{public static main(String[] args){boolean b1=checkString("Hello",s->return s.length()>8);System.out.println(b1);boolean b2=checkString("HelloWorld",s->return s.length()>8);System.out.println(b2);}private static boolean checkString(String s,Predicate<String> pre){return pre.test(); }
}
Function接口
Function<T,R>:常用的两个方法
- R apply(T t):将此函数应用于给定的参数
- default Function andThen(Function after): 返回一个组合数,首先将该函数应用于输入,然后将after函数应用于结果
- Function<T,R>接口通常用于对参数进行处理,转换(处理逻辑由Lambda表达式实现),然后返回一个新的值
class FunctionDemo{public static main(String[] args){String s="伦伦,25";covert(s,ss->{ss.split(",")[1]},ss->Integer::parseInt,i->i+100);}private static void covert(String s,Function<String,String> fun1,Function<String ,Integer> fun2,Function<Integer,Integer> fun3){int i=fun1.abdThen(fun2).andThen(fun3).apply(s);System.out.println(i);}
}