共计 3072 个字符,预计需要花费 8 分钟才能阅读完成。
什么是函数式接口
援用两个中央的定义来尝试地解答下什么是函数式接口
An Interface that contains exactly one abstract method is known as functional interface. It can have any number of default, static methods but can contain only one abstract method. It can also declare methods of object class.
Functional Interface is also known as Single Abstract Method Interfaces or SAM Interfaces. It is a new feature in Java, which helps to achieve functional programming approach.
下面是 javapoint)网站的定义,总结下几点
- 只能有一个 形象函数的接口
- 能够有任一多 默认的动态的 办法
- 能够有 Object 类曾经申明 的办法,因为所有的类都是 Object 的子类
An informative annotation type used to indicate that an interface type declaration is intended to be a functional interface as defined by the Java Language Specification. Conceptually, a functional interface has exactly one abstract method. Since default methods have an implementation, they are not abstract. If an interface declares an abstract method overriding one of the public methods of
java.lang.Object
, that also does not count toward the interface’s abstract method count since any implementation of the interface will have an implementation fromjava.lang.Object
or elsewhere.Note that instances of functional interfaces can be created with lambda expressions, method references, or constructor references.
If a type is annotated with this annotation type, compilers are required to generate an error message unless:
- The type is an interface type and not an annotation type, enum, or class.
- The annotated type satisfies the requirements of a functional interface.
However, the compiler will treat any interface meeting the definition of a functional interface as a functional interface regardless of whether or not a
FunctionalInterface
annotation is present on the interface declaration.
再来看看FunctionalInterface
中的 javadoc,大差不差是一个意思,不过还是能总结出额定的一些小知识点
- 函数式接口的实例能够 应用 lambda示意,办法援用或者构造函数援用
- 带有这个注解的 type 示意这是 接口,而不是注解,枚举或者类
- 函数式接口 能够不带 这个注解,然而带上了这个注解却不是函数式接口的话,编译器将会报错
自定义函数式接口
这里插一句题外话,如果上网搜寻一把函数式接口,能够发现好多常识,那当初写这篇文章仅仅是在反复的炒冷饭吗,其实不是的。网上很多文章千篇一律都是讲了 java 中罕用的函数式接口,就那几样,而且讲得云里雾里的,齐全不是那种新手入门的文章,至多我是看不懂。正是这样,我感觉能够写下我对函数式接口的了解,接下来会从自定义函数式接口切入。
想表白的货色很简略
- 自定义一个 IAnaimal 的接口,外面只有一个形象办法
talk()
。 - 两个具体的实现类实现这个办法。
- 还有主办法调用
talk()
。
IAnimal.java
Cat.java
Dog.java
Main.java
然而有些时候 不想新建一个类 ,比方接口比较简单,实现也不简单,新建一个类可能会冗余,此时有的同学就会想到应用 匿名外部类。
说到匿名外部类,那就代表能够用lambda 表达式再次简化
这样一简化后 IAnimal 就曾经是一个函数接口了,而整个例子也就是自定义函数式接口,所以能够发现它的 实质还是一个接口 ,只不过实现类从一个残缺的类变成了通过 函数 去实现。
java 中罕用的函数式接口
下面讲了一个简略的自定义函数式接口的例子,接下来再看下 jdk 自身就申明的 四大函数式接口。
函数式接口 | 参数类型 | 返回类型 | 用处 | 次要办法 |
---|---|---|---|---|
Consumer\<T> | T | void | 生产类型为 T 的对象 | void accept(T t) |
Supplier\<T> | 无 | T | 返回类型为 T 的对象 | T get() |
Function<T, R> | T | R | 操作类型为 T 的对象,返回 R 类型的对象 | R apply(T t) |
Predicate\<T> | T | boolean | 确定类型为 T 的对象是否满足束缚,返回 boolean | boolean test(T t) |
Consumer
输入如下
Supplier
对于 supplier 来说,切实是找不到啥比拟好的例子,或者找到的例子都非常简略,这里略微说下supplier 的懒加载个性,看下输入
Function
输入:
Predicate
输入:
破产版实现 ArrayList 中的 forEach
可能老手同学们没太听过函数式接口,然而平时编码开发中的 list 里的 forEach 入参就是一个函数式接口
接下来参考源码实现一个 破产版的 List 和 List 中的 forEach,总共有以下几个步骤
- 新建一个 Student 对象
- 自定义一个 list,外面有个 Student 数组存元素,还有一个 add 办法和 forEach 办法(应用 Consumer)
- 革新办法,自定义一个函数式接口代替 Consumer
Student
MyList
ForEachMain
看下输入:
IAnyway
自定义一个函数式接口,实质上就是 Consumer,而后类名和办法名改了一下,这样的目标是通知老手同学 jdk 中的 4 大函数式接口不是什么神奇的货色,它们实质上就是接口,只不过是 jdk 总结了咱们罕用的场景来申明了这些函数式接口,防止了反复去申明一样作用的函数式接口。
定义了接口后,在来看看MyList
类
应用的中央也批改一下
输入:
思考
洋洋洒洒也写了一点,写完发现更迷糊了,我是晓得函数式接口是啥了,甚至在工作的编码中也强制本人用了一把函数接口,还合入了公司的代码仓。然而,什么时候 什么状况下应用函数接口 还始终困惑着我,包含 google,baidu,statckoverflow 都没有一个比拟好的答案。于 目前的我 而言,函数式接口仿佛和匿名外部类,和 lambda 表达式是一个货色。
参考文献
Java 8 Functional Interfaces – javatpoint