相关阅读
【小家java】java5新特性(简述十大新特性) 重要一跃
【小家java】java6新特性(简述十大新特性) 鸡肋升级
【小家java】java7新特性(简述八大新特性) 不温不火
【小家java】java8新特性(简述十大新特性) 饱受赞誉
【小家java】java9新特性(简述十大新特性) 褒贬不一
【小家java】java10新特性(简述十大新特性) 小步迭代
【小家java】java11新特性(简述八大新特性) 首个重磅LTS版本
【小家java】java8新特性之—Base64加密和解密原理
【小家java】java8新特性之—反射获取方法参数名
【小家java】java8新特性之—全新的日期、时间API(完全实现了JSR 310规范)
【小家java】java8新特性之—Optional的使用,避免空指针,代替三目运算符
【小家java】java8新特性之—lambda表达式的的原理
【小家java】java8新特性之—函数式接口(Supplier、Consumer、Predicate、Function、UnaryOperator,通往高阶设计的好工具)
【小家java】java8新特性之—方法引用
【小家java】java8新特性之—Stream API 详解 (Map-reduce、Collectors收集器、并行流)
【小家java】java8新特性之—外部迭代和内部迭代(对比性能差异)
每篇一句
再穷不要借了钱过后消失。再难,不要说话不算数。堂堂正正的做人,明明白白的做事,永远不要丢掉别人对你的信任。因为别人信任你是在别人心目中存在的价值。人生路很长,自己不要把路走窄了
什么是函数式接口?
所有函数式接口都在这个包:java.util.function
首先,它还是一个接口,所以必须满足接口最基本的定义。但它是一个特殊的接口:SAM类型的接口(Single Abstract Method)。可以在调用时,使用一个lambda表达式作为参数。
定义要求:
1.只能有一个抽象方法需要被实现
@FunctionalInterface interface Converter<F, T> { T convert(F from); }
备注:此处不包括与Object的public方法(clone方法不行,因为clone方法是protected,编译会报错)重名的方法。当然里面的默认方法、static方法都是无所谓的
default 修饰的默认方法方法,这个关键字是Java8中新增的,为的目的就是使得某一些接口,原则上只有一个方法被实现,但是由于历史原因,不得不加入一些方法来兼容整个JDK中的API,所以就需要使用default关键字来定义这样的方法
2.可以有从Object继承过来的抽象方法,因为所有类的最终父类都是Object
3.接口中唯一抽象方法的命名并不重要,因为函数式接口就是对某一行为进行抽象,主要目的就是支持Lambda表达式。
以下附JDK 8之前已有的函数式接口:
java.lang.Runnable
java.util.concurrent.Callable
java.security.PrivilegedAction
java.util.Comparator
java.io.FileFilter
java.nio.file.PathMatcher
java.lang.reflect.InvocationHandler
java.beans.PropertyChangeListener
java.awt.event.ActionListener
javax.swing.event.ChangeListener
Java8还提供了@FunctionalInterface注解来帮助我们标识函数式接口。所以Java8后上面那些接口都被打上了这个标记。
下面给出一张图:说出Java8新提供的函数式接口们(可以满足99%需求):
四大核心函数式接口:
public interface Supplier
其简洁的声明,会让人以为不是函数。这个抽象方法的声明,同Consumer相反,是一个只声明了返回值,不需要参数的函数(这还叫函数?)。也就是说Supplier其实表达的不是从一个参数空间到结果空间的映射能力,而是表达一种生成能力。
Supplier<String> supplier = String::new;
其他Supplier扩展接口:
BooleanSupplier:boolean getAsBoolean();返回boolean
DoubleSupplier:double getAsDouble();返回double
IntSupplier:int getAsInt();返回int
LongSupplier:long getAsLong();返回long
public interface Consumer
这个接口声明太重要了,应用场景太多了。因为需要返回值的我们用Function,不需要返回值的,我们用它就可。
Consumer consumer = System.out::println;
看其源码 还有个默认方法andThen:
void accept(T t); default Consumer<T> andThen(Consumer<? super T> after) { Objects.requireNonNull(after); return (T t) -> { accept(t); after.accept(t); }; }
andThen可以实现消费两次。消费一次后,继续消费一次。使用场景:
其他Consumer扩展接口:
BiConsumer:void accept(T t, U u);接受两个参数
DoubleConsumer:void accept(double value);接受一个double参数
IntConsumer:void accept(int value);接受一个int参数
LongConsumer:void accept(long value);接受一个long参数
ObjDoubleConsumer:void accept(T t, double value);接受一个泛型参数一个double参数
ObjIntConsumer:void accept(T t, int value);接受一个泛型参数一个int参数
ObjLongConsumer:void accept(T t, long value);接受一个泛型参数一个long参数