好处:简洁、易读、高效(搭配Stream API并行处理)
用处:
-
能根据此处需要的参数,自动地创建对应的已存在的函数式接口的 匿名实现类
(根据实参,提供实现类)
- 函数式接口:只存在一个抽象方法的接口,它被看作是一个函数的签名。
用 @FunctionalInterface可以修饰接口,表示该接口是只有一个抽象方法的函数式接口
1.无参
interface ZSLSwimmable { (自定义函数式接口,有且只有一个抽象方法的接口)
public abstract void swimming();
}
public static void goSwimming(ZSLSwimmable swimmable) {
//调用游泳动作,实现游泳
swimmable.swimming();
}
public static void main(String[] args) {
goSwimming(new ZSLSwimmable () {
@Override
public void swimming() {
System.out.println("匿名内部类游泳");
}
});
goSwimming(() -> {
System.out.println("Lambda游泳");
});
}
2.有参:
(参数列表, ...) -> { 方法体; }
这种情况可以使用省略写法:
(int a) -> { return new Person(); } 只有一个参数,一条语句,省略(类型 return ;)
a -> new Person()
函数式接口的由来:接口默认方法、接口静态方法(接口增强)
默认方法好处:更加利于了接口扩展 ,打破了jdk8之前“接口不能有方法实现”的说法
为了增强接口的扩展性,避免强制实现的抽象方法,出现了默认方法
interface 接口名 {
静态常量;
抽象方法; abstract
//新增↓
默认方法; default
静态方法; static
}
静态方法好处:可看作是一个接口内置的工具,可以为接口的实现类提供一些便利的操作。
虽然可以直接通过 接口名.静态方法 进行调用,但设计初衷的规范是一般用于实现类进行调用
2、Lamdba函数式接口
由于lamdba只需要关心抽象方法的参数 和 返回值,为了方便使用,出现了一些常用的函数式接口,来为lamdba制定规范,省的手写函数式接口
@FunctionalInterface
public interface Supplier<T> { 生产加强者,返回指定参数类型
public abstract T get();
}
@FunctionalInterface
public interface Consumer<T> { 消费者,仅消费
public abstract void accept(T t);
defunct Consumer andThen(多个Consumer) 额外默认方法(指定多个消费者顺序,以消费者A返回后消费B
}
默认方法使用:
test(s -> System.out.println(s.toLowerCase()),
s ->System.out.println(s.toUpperCase()));
}
public static void test(Consumer<String> c1, Consumer<String > c2) {
String str = "Hello World";
c1.andThen(c2).accept(str); //c1先执行,以c1返回基础再执行c2的accept
}
也就是先小写后大写
@FunctionalInterface
public interface Function<T, R> { 生产转换者,经T返回R
public abstract R apply(T t);
同样有andThen 默认方法,经T返回R,接着经R返回X
}
@FunctionalInterface
public interface Predicate<T> { 判断者
public abstract boolean test(T t);
默认方法 and 传入多个,同时满足
默认方法 or 传入多个,一个以上满足
默认方法 negate 判断取反后的test结果
}
3、Lambda方法引用
好处:简化lambda,提高复用性
如果Lambda所要实现的方案 , 已经有其他方法存在相同方案,那么则可以使用方法引用。
仅限于提供给函数式接口,作为一种方案传递
比如快捷完成runnable实现和创建和启动(test内容作为run方法体,用匿名实现类实现runnable):
public class T3{
private static void test(){
System.out.println("66");
}
public static void main(String[] args) {
new Thread(T3::test).start();
}
}
1.对象名::对象方法
Date now = new Date();
Supplier<Long> supp2 = now::getTime;
System.out.println(supp2.get());
2.类名::静态方法
Supplier<Long> supp2 = System::currentTimeMillis;
System.out.println(supp2.get());
3.类名::引用实例方法
class QWE{
public void qwe() {
}
}
psvm:
Consumer<QWE> f2=QWE::qwe;
Function<String, Integer> f3 = String::length;(返回integer)
4.类名/数组 ::new引用构造器
Supplier<Person> sup2 = Person::new;
System.out.println(sup2.get());
Function<Integer, String[]> fun2 = String[]::new;
String[] arr2 = fun.apply(5);