Java8新特性 | 四大函数式接口及其扩展接口

本文源码:Gitee·点这里

什么是函数式接口

在介绍他们之前,我们先看看什么是函数式接口。先打开API文档,查看FunctionalInterface的介绍。

FunctionalInterface

API中介绍可以看出:

  • @FunctionalInterface是一个注解,旨在声明接口类型为函数式接口,切只能加在接口上。

  • 函数式接口只允许有一个抽象方法

  • 可以包含使用default声明的方法,因为该方法为普通方法(Java8以后允许在接口中使用default声明一个普通方法)

  • 可以使用Lambada表达式创建函数式接口的实例

注:如果接口符合函数式接口的要求,即使不加@FunctionalInterface注解也会被视为函数式接口

四大函数式接口有哪些

java.util.function包的介绍可以看出,Java有四大函数式接口,分别为FunctionConsumerPredicateSupplier,我们来逐个介绍,相信看完后你会对函数式接口有更深的理解。

java.util.function

Function<T, R> 函数型接口

表示接收一个参数并返回结果的函数。该函数式接口方法为R apply(T t)

  • <T> 为入参泛型

  • <R> 为返回结果泛型

示例代码

示例1:函数式接口可以被new出一个实例来,必须实现其抽象接口

static void functionDemo1() {
    Function<Integer, String> function = new Function<Integer, String>() {
        @Override
        public String apply(Integer integer) {
            return integer.toString() + "程序员节";
        }
    };
    System.out.println("functionDemo1 --> " + function.apply(1024));
}

示例2:可以使用Lambada表达式简化函数式接口

static void functionDemo2() {
    Function<Integer, String> function = (integer) -> {
        return integer.toString() + "程序员节";
    };
    System.out.println("functionDemo2 --> " + function.apply(1024));
}

示例3:Lambada表达式入参只有一个时,可以不加小括号;
方法体内只有一行代码时可以不加大括号和 return 关键字,直接编写返回结果即可

static void functionDemo3() {
    Function<Integer, String> function = integer -> integer.toString() + "程序员节";
    System.out.println("functionDemo2 --> " + function.apply(1024));
}

示例4:函数式接口做为方法的入参

static void functionDemo4(Integer integer, Function<Integer, String> function) {
    System.out.println("functionDemo4 --> " + function.apply(integer));
}

public static void main(String[] args) {
    functionDemo4(1024, integer -> integer.toString() + "程序员节");
}

Predicate<T> 断定型接口

表示接收一个参数,判断该参数是否满足某约束,并返回boolean值。该函数式接口方法为boolean test(T t)

  • <T> 为入参泛型
  • 返回boolean型值

示例代码

示例1:new一个Predicate实例

static void predicateDemo1() {
    Predicate<Integer> predicate = integer -> integer == 1024;
    System.out.println("predicateDemo1 --> " + predicate.test(1024));
}

示例2:Predicate做为方法的入参

static void predicateDemo2(Integer integer, Predicate<Integer> predicate) {
    System.out.println("predicateDemo1 --> " + predicate.test(integer));
}

public static void main(String[] args) {
    predicateDemo2(1024, integer -> integer == 1024);
}

Consumer<T> 消费型接口

接收一个参数但不返回结果,表示为消费者。该函数式接口方法为void accept(T t)

  • <T> 为入参泛型

示例代码

示例1:new一个Consumer实例

static void consumerDemo1() {
    Consumer<Integer> consumer = integer -> System.out.println("consumerDemo1 --> " + integer);
    consumer.accept(1024);
}

示例2:Consumer 作为方法的入参

static void consumerDemo2(Integer integer, Consumer<Integer> consumer) {
    consumer.accept(integer);
}

public static void main(String[] args) {
    consumerDemo2(1024, integer -> System.out.println("consumerDemo2 --> " + integer));
}

Supplier<T> 供给型接口

Consumer相反,Supplier只有返回结果,表示为提供者。该函数式接口方法为T get()

  • <T> 为返回结果泛型

示例代码

示例1:new一个Supplier实例

static void supplierDemo1() {
    Supplier<Integer> supplier = () -> 1024;
    System.out.println("supplierDemo1 --> " + supplier.get());
}

示例2:Supplier作为方法的入参

static void supplierDemo2(Supplier<Integer> supplier) {
    System.out.println("supplierDemo2 --> " + supplier.get());
}

public static void main(String[] args) {
    supplierDemo2(() -> 1024);
}

四大函数式接口总结

为了便于记忆,我们对四大函数式接口进行一个总结:

函数式接口 接口类型 参数类型 返回类型 方法
Function<T, R> 函数型接口 T R R apply(T t)
Predicate<T> 断定型接口 T boolean boolean test(T t)
Consumer<T> 消费型接口 T void void accept(T t)
Supplier<T> 供给型接口 T T get()

其他函数式接口(扩展)

java.util.function包下还包含了其他函数式接口供我们使用,也是对这四大函数式接口进行的一个扩展

函数型接口

函数式接口 参数类型 返回类型 方法 用途
BiFunction<T,U,R> T,U R R apply(T t, U u) 接收两个输入参数并产生结果
ToIntBiFunction<T,U> T,U int int applyAsInt(T t,U u) 接收两个输入参数并返回int类型结果
ToLongBiFunction<T,U> T,U long long applyAsLong(T t, U u) 接收两个输入参数并返回long类型结果
ToDoubleBiFunction<T,U> T,U double double(T t, U u) 接收两个输入参数并产生double类型结果
ToIntFunction<T> T int int applyAsInt(T value) 接收一个参数并返回int类型结果
ToDoubleFunction<T> T double double applyAsDouble(T value) 接收一个参数并返回double类型结果
IntFunction<R> int R R apply(int value) 接收一个int类型参数,并返回结果
LongFunction<R> long R R apply(long value) 接收一个long类型参数,并返回结果
DoubleFunction<R> double R R apply(double value) 接收一个double类型参数,并返回结果
IntToDoubleFunction int double double applyAsDouble(int value) 接收一个int类型参数,返回double类型结果
LongToDoubleFunction long double double applyAsDouble(long value) 接收一个long类型参数,返回double类型结果
LongToIntFunction long int int applyAsInt(long value) 接收一个long类型参数,返回int类型结果
IntToLongFunction int long long applyAsLong(int value) 接收一个int类型参数,返回long类型结果
DoubleToIntFunction double int int applyAsInt(double value) 接收一个double类型参数,返回int类型结果
DoubleToLongFunction double long long applyAsLong(double value) 接收一个double类型参数,返回long类型结果
BinaryOperator<T> T,T T T apply(T t1, T t2) BiFunction<T,T,T>的一个子接口,表示对同一类型的两个参数进行操作,产生同一类型的结果
UnaryOperator<T> T T T apply(T t) Function<T,T>的一个子接口,表示对单个参数操作,产生同一类型的结果
LongBinaryOperator long,long long long applyAsLong(long left, long right) 对两个long值计算并产生long结果
DoubleBinaryOperator double,double double double applyAsDouble(double left, double right) 对两个double值计算并产生double结果
IntUnaryOperator int int int applyAsInt(int operand) 对单个int值操作,产生一个int结果
LongUnaryOperator long long long applyAsLong(long operand) 对单个long值操作,产生一个long结果
DoubleUnaryOperator double double double applyAsDouble(double operand) 对单个double值操作,返回一个double结果
IntBinaryOperator int,int int int applyAsInt(int left, int right) 对两个int值计算并产生int结果

断定型接口

函数式接口 参数类型 返回类型 方法 用途
BiPredicate<T,U> T,U boolean boolean test(T t, U u) 接收两个输入参数,断定并返回boolean类型结果
IntPredicate int boolean boolean test(int value) 接收一个int参数值,断定并返回boolean类型结果
LongPredicate long boolean boolean test(long value) 接收一个long类型参数,断定并返回boolean类型结果
DoublePredicate double boolean boolean test(double value) 接收一个double参数值,断定并返回boolean类型结果

消费型接口

函数式接口 参数类型 返回类型 方法 用途
BiConsumer<T,U> T,U void void accept(T t, U u) 接收两个输入参数,不返回结果
ObjIntConsumer<T> T,int void void accept(T t, int value) 接收对象值和int类型参数,不返回结果
ObjLongConsumer<T> T,long void void accept(T t, long value) 接收对象值和long类型参数,不返回结果
ObjDoubleConsumer<T> T,double void void accept(T t, double value) 接收对象值和double类型参数,不返回结果
LongConsumer long void void accept(long value) 消费long类型值,不返回结果
DoubleConsumer double void void accept(double value) 消费double类型值,不返回结果
IntConsumer int void void accept(int value) 消费int类型值,不返回结果

供给型接口

函数式接口 参数类型 返回类型 方法 用途
BooleanSupplier boolean boolean getAsBoolean() 表示供给boolean类型的结果
IntSupplier int int getAsInt() 表示供给int类型的结果
LongSupplier long long getAsLong() 表示供给long类型的结果
DoubleSupplier double double getAsDouble() 表示供给double类型的结果
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,997评论 6 502
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,603评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,359评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,309评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,346评论 6 390
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,258评论 1 300
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,122评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,970评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,403评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,596评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,769评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,464评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,075评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,705评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,848评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,831评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,678评论 2 354