函数式接口概述
函数式接口:
有且仅有一个抽象方法的接口
Java中的函数式编程体现就是Lambda表达式,所以函数式接口就是可以适用于Lambda使用的接口
只要确定了该接口有且仅有一个抽象方法,那么Lambda表单式就可以推导
Lambda表达式: 使用Lambda表达式的前提是该类是一个接口,并且有且仅有一个抽象方法
函数式接口 -> Lambda表达式
函数式接口的对象:
1.可以用作方法传递
2.同样可以是局部变量
代码实例:
public class Test {
public static void main(String[] args) {
// 函数式接口被当做局部变量的时候,可以直接赋值Lambda表达式
InterfaceTest it =()-> System.out.println(“函数式接口”);
it.show(); } }
检验接口是否为函数式接口
函数式接口注释:
@FunctionalInterface
代码实例:
// 定义一个有且只有一个方法的函数式接口,为了更好的区别函数式接口和其他接口的区别
// Java提供了@FunctionInterface注解标记函数式接口
_@FunctionalInterface
_public interface InterfaceTest { void show();}
Tips:
我们定义函数式接口的时候,@FunctialInterface是可选的,就算我不写这个注解,只要保证满足函数式接口定义的条件,也照样是函数式接口,建议加上注释
函数式接口作为方法的参数
需求:
- 定义一个类(RunnableDemo),在类中提供两个方法
- 一个是:startThread(Runnable r)方法参数Runnable是一个函数是借口
- 一个方法是主方法,在主方法中调用startThread方法
- 如果方法的参数是一个函数式接口,我们可以将Lambda表达式作为参数直接传递
- startThread)(()->System.out.println(Thread.currentThread().getName()+”启动”));
- 通俗理解就是如果知道调用的接口是函数式接口,可以不用刻意去创建对象实现,直接调用Lambda实现即可
- 函数接口是可以作为方法的参数直接用Lambda实现的,并不只是这一种匿名实现
public class RunnableDemo {
public static void main(String[] args) {
startThread(() -> System.out.println(Thread.currentThread().getName() + “ Lambda启动”));
// 匿名内部类调用方法
startThread(new Runnable() {
@Override
_public void run() {
System.out.println(Thread.currentThread().getName() + “ 匿名内部类启动”); } }); }
private static void startThread(Runnable _r) {
// Runnable是只有一个抽象方法的接口是函数式接口
/ Thread t = new Thread(r);
t.start();/
// 使用匿名类
new Thread(r).start(); }
函数式接口作为方法的返回值
需求:
- 定义一个类(ComparatorDemo),在类中提供两个方法
- 一个是方法是:Comparator
getComparator() - 定义返回值是Compartor, 而方法返回值Comparator是一个函数式接口
- 一个方法是主方法,在主方法中调用getComparator方法
- 一个是方法是:Comparator
- 如果方法的返回值是一个函数式接口,我们可以将Lambda表达式作为结果返回
- private Comparator
getComparator(){ return(s1,s2)->s1.length() -s2.length();}
- private Comparator
public class ComparatorDemo {
public static void main(String[] args) {
// 构造使用场景,定义集合存储字符串
ArrayList<String> al = new ArrayList<>();
al.add(“e”);
al.add(“aaaaa”);
al.add(“ccc”);
al.add(“dd”);
al.add(“bbbb”);
System.out.println(“排序前: “ + al);
// 使用Collections集合工具类的sort()自然排序方法排序
Collections.sort(al);
// 自然排序后: [aaaaa, bbbb, ccc, dd, e]
// 使用Collections集合工具类的sort()中带比较器接口的方法
// getComparator()定义比较器的方法中是比较长度
Collections.sort(al,getComparator());
System.out.println(“自然排序后: “ + al);
// 自然排序后: [e, dd, ccc, bbbb, aaaaa] **}
**private static Comparator**<**String**> **getComparator**() {<br /> **// Comparable是一个函数是接口<br /> // 只有一个抽象方法 public int compareTo(T o);<br /> // 匿名内部类实现<br /> Comparator**<**String**> **cp = new Comparator**<**String**>() {<br /> **_@Override<br /> _public int compare**(**String _s1_, String _s2_**) {<br /> **return _s1_.length**() **- _s2_.length**()**; **} }**;<br /> return cp;<br /> // 返回cp这个对象就是返回匿名内部类,可以直接返回<br /> return new Comparator<String>(){<br /> _@Override<br /> _public int compare(String _s1_, String _s2_) {<br /> return _s1_.length() - _s2_.length(); } };<br /> // Lambda表达式实现比较比较器函数是接口比较长度<br /> return **(**String _s1 _,String _s2_**)**->**{ **return _s1_.length**() **- _s2_.length**()**; **}**;<br /> // 简化Lambda表达式<br /> return **(**_s1_, _s2_**) **-> _s1_.length**() **- _s2_.length**()**;<br /> // 简化使用方法饮用String比较字符串长度String::length<br /> return Comparator.**comparingInt(**String::length**)**; **} }**
常用的函数式接口
- **Supplier接口**
- **Consumer接口**
- **Predicate接口**
- **Function接口**
函数式接口之Supplier接口
Supplier
- T get(): 获得结果
- 该方法不需要参数,这是一个功能界面,可以按照某种实现逻辑(由Lambda表达式实现)返回一个数据
- Supplier
接口也被称为生产型接口,就是我们指定了接口的泛型是什么类型,那么Supplier 这个T是什么类型,该接口的get()方法就是什么类型的数据
函数式接口之Consumer接口
Consumer
- void accept(T t) 对给定的参数执行此操作
- default Consumer
andThen(Consumer<? super T> after) - 返回一个组合的 Consumer ,按顺序执行该操作,然后执行 after操
- Consumer
接口也被称为消费性接口。它使用数据的类型由泛型指定
函数式接口之Predicate接口
Predicate
- boolean test(T t) 在给定的参数上评估这个谓词。
- default Predicate
negate() 返回表示此谓词的逻辑否定的谓词。 - default Predicate
and(Predicate<? super T> other) - 返回一个组合的谓词,表示该谓词与另一个谓词的短路逻辑AND。
- 有false就是false
- default Predicate
or(Predicate<? super T> other) - 返回一个组合的谓词,表示该谓词与另一个谓词的短路逻辑或。
- 有true则true,
- Predicate
接口通常用于判断参数是否满足指定的条件
public class Test {
public static void main(String[] args) {
String[] strArray = {“王五,22”, “张曼玉,34”, “林青霞,21”, “李四,34”, “张三,33”};
ArrayList<String> al = usePredicate(strArray, s -> s.split(“,”)[0].length() > 2,
s -> Integer.parseInt(s.split(“,”)[1]) > 33);
for (String s : al) {
System.out.println(s); **} }
**private static ArrayList**<**String**> **usePredicate**(**String**[] **_str_, Predicate**<**String**> **_p1_, Predicate**<**String**> **_p2_**) {
**ArrayList**<**String**> **al = new ArrayList**<>()**;<br /> for **(**String s : _str_**) {<br /> **// 使用Predicate函数是借口中的and()和test()方法判断<br /> if **(**_p1_.and**(**_p2_**)**.test**(**s**)){<br /> **al.add**(**s**)**; **} }<br /> **return al; **} }**
函数式接口之Function接口
Function
- R apply(T t) 将此函数应用于给定的参数。
- default
Function andThen(Function<? super R,? extends V> after) - 返回一个组合函数,首先将该函数应用于其输入,然后将 after函数应用于结果。
- Function
接口通常用于对参数进行处理, 转换然后返回一个新的值
public class Test {
public static void main(String[] args) {
String 李畅 =”李畅,26”;
useFunction(李畅, s -> s.split(“,”)[1], Integer::parseInt,
integer -> integer+70); **}
private static void useFunction(String s, Function<String,String>f1,Function<String,Integer> f2,Function<Integer,Integer> f3) {
int i = f1.andThen(f2).andThen(f3).apply(s);
System.out.println(i); } }