package java.lang; import java.lang.annotation.*; /** * An informative annotation type used to indicate that an interface * type declaration is intended to be a <i>functional interface</i> as * defined by the Java Language Specification. * * Conceptually, a functional interface has exactly one abstract * method. Since {@linkplain java.lang.reflect.Method#isDefault() * default methods} have an implementation, they are not abstract. If * an interface declares an abstract method overriding one of the * public methods of {@code java.lang.Object}, that also does * <em>not</em> count toward the interface's abstract method count * since any implementation of the interface will have an * implementation from {@code java.lang.Object} or elsewhere. * * <p>Note that instances of functional interfaces can be created with * lambda expressions, method references, or constructor references. * * <p>If a type is annotated with this annotation type, compilers are * required to generate an error message unless: * * <ul> * <li> The type is an interface type and not an annotation type, enum, or class. * <li> The annotated type satisfies the requirements of a functional interface. * </ul> * <p>However, the compiler will treat any interface meeting the * definition of a functional interface as a functional interface * regardless of whether or not a {@code FunctionalInterface} * annotation is present on the interface declaration. * * @jls 4.3.2. The Class Object * @jls 9.8 Functional Interfaces * @jls 9.4.3 Interface Method Body * @since 1.8 */ @Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface FunctionalInterface {}
函数式接口只有一个抽象方法
因为default方法有一个实现,因此他们不是抽象的.
若是一个接口定义了一个抽象方法,而他刚好覆盖了Object的public方法,仍旧不算作接口的抽象方法, 由于它终将会在某处获得一个实现.(若是不是public的那么计数)
也便是只有一个抽象方法默认不算,Object的public也不算
|
函数式接口的实例能够经过 lambda表达式 方法引用 或者构造方法引用进行表示 |
类型必须是接口,而不能是其余的好比class 并且须要符合函数式接口的定义要求 不然使用注解时编译器报错 |
无论他们是否有使用注解FunctionalInterface 进行注解, 编译器将会把任何知足函数式接口定义的接口当作一个函数式接口 也就是说不加也行,可是显然不加的话,就没有限制约束,后续可能增长了其余方法致使出错 |
接口 抽象方法
|
java.util.function.Predicate<T>
断言 也就是条件测试器 接收条件,进行测试
接口定义了一个名叫test的抽象方法,它接受泛型T对象,并返回一个boolean。
test (条件测试) , and-or- negate(与或非) 方法
|
java.util.function.Consumer<T>
消费者 消费数据 接收参数,返回void 数据被消费了
定义了一个名叫accept的抽象方法,它接受泛型T的对象,没有返回(void)
你若是须要访问类型T的对象,并对其执行某些操做,就可使用这个接口
|
java.util.function.Function<T, R>
函数 有输入有输出 数据转换功能
接口定义了一个叫做apply的方法,它接受一个泛型T的对象,并返回一个泛型R的对象。
|
java.util.function.Supplier<T> 提供者 不须要输入,产出T 提供数据 无参构造方法 提供T类型对象 |
接口中的compose, andThen, and, or, negate 用来组合函数接口而获得更强大的函数接口
四大接口为基础接口,其余的函数接口都是经过这四个扩展而来的
此处的扩展是指概念的展开 不是日常说的继承或者实现,固然实现上多是经过继承好比UnaryOperator
|
加了类型前缀[Int|Double|Long] 表示参数是基本类型, 若是在此基础上又加上了To 表示返回类型是基本类型 |
(parameters) -> expression |
(parameters) -> { statements; } |
() -> {System.out.print("Hello");System.out.println(" World");};
class A { private String s1="a"; private String s2="b"; private String s3="c"; A(){ } A(String s1){ this.s1=s1; } A(String s1,String s2){ this.s1=s1; this.s2=s2; } A(String s1,String s2,String s3){ this.s1=s1; this.s2=s2; this.s3=s3; } @Override public String toString() { final StringBuilder sb = new StringBuilder("A{"); sb.append("s1='").append(s1).append('\''); sb.append(", s2='").append(s2).append('\''); sb.append(", s3='").append(s3).append('\''); sb.append('}'); return sb.toString(); } }
函数式接口 变量名 = Lambda-匿名函数/方法引用/构造方法引用; |
List<Integer> listNum = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9); java
List filteredNum = listNum.stream().filter(i -> i.compareTo(5) < 0).collect(Collectors.toList()); web
System.out.println(filteredNum);
express
1. 经过形参类型或者变量类型 找到函数接口进而找到抽象方法的声明
2. 而后在与参数值进行比对查看是否匹配
|
若是不一样的函数接口,具备相互兼容的抽象方法签名 那么一个Lambda表达式显然能够匹配多个函数接口
|
特殊的void兼容规则
若是一个Lambda的主体是一个语句表达式, 它就和一个返回void的函数描述符兼容(固然须要参数列表也兼容)。
就是说 若是主体是一个语句,无论作什么或者调用方法返回其余的类型,他均可以兼容void
|
List<String> list= new ArrayList<>(); app
// Predicate返回了一个boolean less
Predicate<String> p = s -> list.add(s); ide
// Consumer返回了一个void 函数
Consumer<String> b = s -> list.add(s);
性能
List<String> list = new ArrayList<String>(); |
List<String> list = new ArrayList<>(); |
.filter((Integer i) -> { return i.compareTo(5) < 0;}).collect(Collectors.toList()); 测试
.filter((Integer i) ->i.compareTo(5) < 0).collect(Collectors.toList()); ui
.filter(i ->i.compareTo(5) < 0).collect(Collectors.toList());