java.util.function中的函数式接口


前言:针对与jdk1.8的新特性(流),java.util.function包下的函数式接口的学习是必不可少的。lambda表达式的入参除了普通的入参,大部分都是以lambda表达式作为方法的入参。如{(a, b) -> a + b}。本文通过我对部分函数式接口的理解以及自我测试,总结出部分函数式接口的基本使用方式。

Java 8 中的 Streams API 详解 新手入门可观看Stream使用详解以及Stream的介绍。

函数式接口

Function

jdk1.8介绍

@FunctionalInterface

public interface Function

表示接受一个参数并产生结果的函数。

这是一个functional interface的功能方法是apply(Object)

T -> 函数接收参数的类型

R -> 函数返回结果的类型

// TODO 接收T类型的参数,返回R类型的结果
R apply(T t); // Function默认的调用方式

Function<Object, String> function = (s) -> {
    return s.toString().UpperCase();
}
function.apply("function");
// 输出结果:"FUNCTION"

UnaryOperator

jdk1.8介绍

@FunctionalInterface

public interface UnaryOperator

extends Function<T,T>

表示对单个操作数产生与其操作数相同类型的结果的操作。对于操作数和结果是相同类型的情况,这是Function的Function

这是一个functional interface的功能方法是Function.apply(Object)

// TODO 接收T类型的参数,返回T类型的结果
T apply(T t); // UnaryOperator 默认的调用方式

// TODO 接收一个String类型的参数,返回一个String类型的值。既是生产者又是消费者
UnaryOperator<String> unaryOperator = (s) -> {
    return s.trim().toUpperCase();
}

unartOperator.apply(" test "); // 输出结果:"TEST";

BiFunction

jdk1.8介绍

@FunctionalInterface

public interface BiFunction

表示接受两个参数并产生结果的函数。这是Function的二元专业化 。

这是一个functional interface的功能方法是apply(Object, Object)

T -> 函数接收第一个参数的类型

U -> 函数接收第二个参数的类型

R -> 函数返回结果的类型

// TODO 接收T类型和U类型的参数,返回R类型的结果
R apply(T t, U u); // BiFunction 默认的调用方式

// TODO 打印输入两个参数的字符长度
BiFunction<Object, String, Integer> biFunction = (s1, s2) -> {
    return s1.toString().length() + s2.length();
};
Integer result = biFunction.apply("woshi", "xiaohei");
System.out.println(result); // 输出结果:12

BinaryOperator

jdk1.8介绍

@FunctionalInterface

public interface BinaryOperator

extends BiFunction

表示对同一类型的两个操作数的操作,产生与操作数相同类型的结果。对于操作数和结果都是相同类型的情况,这是BiFunction的专业化 。

这是一个functional interface的功能方法是BiFunction.apply(Object, Object)

// TODO 接收两个T类型的参数,返回T类型的结果
T apply(T t1, T t2); // BinaryOperator 默认的调用方式

// TODO 例子:拼接接收的两个String参数
BinaryOperator<String> binaryOperator = (s1, s2) -> s1 + s2;
String result = binaryOperator.apply("a", "b");
// 输出结果:“ab”;

从接口的定义来说,BiFunction比Function多了一个入参,也使得BiFunction在一些业务场景上更灵活些。但其实本质上,他们的调用方式都是使用apply()进行调用

Predicate

jdk1.8介绍

@FunctionalInterface

public interface Predicate

表示一个参数的谓词(布尔值函数)。

这是一个functional interface的功能方法是test(Object)

简述:Predicate表达式 <==> 逻辑判断语句

// TODO 接收T类型参数,返回boolean类型的结果
boolean test(T t); // Predicate 默认的调用方式

// TODO Predicate接收返回boolean类型的逻辑表达式。
Predicate predicate = pre -> "aa".equals(pre);
boolean result = predicate2.test("aa");
System.out.println(result);

Supplier

jdk1.8介绍

@FunctionalInterface

public interface Supplier

代表结果供应商。

没有要求每次调用供应商时都会返回新的或不同的结果。

这是一个functional interface的功能方法是get()

// Teacher{"name":"", "school":"", "subject":""}
// TODO 使用Supplier函数式接口创建一个默认的Teacher对象。
// TODO 不接受任何参数,但是返回一个类型的对象。 ==> 生产者
Supplier<Teacher> teacherSupplier = () -> {
    Teacher t = new Teacher();
    t.setName("张三");
    t.setSchool("某市一中");
    t.setSubject("语文");
    return t;
}
// 获取一个默认的Teacher对象。
// 默认信息为Teacher{"name":"张三", "school":"某市一中", "subject":"语文"}
teacherSupplier.get();

// 使用Teacher::new创建Supplier<Teacher>对象。
Supplier<Teacher> teacherSupplier2 = Teacher::new;
// teacherSupplier2.get() 获取到的Teacher对象默认信息为null
teacherSupplier2.get();

Consumer

jdk1.8介绍

@FunctionalInterface

public interface Consumer

表示接受单个输入参数并且不返回结果的操作。与大多数其他功能界面不同, Consumer预计将通过副作用进行操作。

这是一个functional interface的功能方法是accept(Object)

// TODO 接收T类型
void accept(T t); // Consumer 默认的调用方式

// TODO Consumer :该函数式接口接收一个参数,但不返回任何类型的值。==>消费者
Consumer<String> consumer = (s) -> {
    System.out.println(s.trim().toUpperCase());
}
consumer.accept("  consumer   ");
// 输出结果:"CONSUMER"

函数式接口总结

接口 参数 返回类型 调用方法 描述
Predicate T boolean test(T t) 默认接收返回boolean参数类型的值
BinaryOperator T T apply(T t1, T t2) extends BiFunction<T, T, T>。接收两个T类型的参数,返回T类型的数据
Supplier none T get(); 生产者。不接受任何参数,但是返回T类型的参数
Consumer T none accept(T t); 消费者。接收T类型的参数,但是不返回任何数据
UnaryOperator T T apply(T t); extends Function<T, T>。接收T类型的参数,返回T类型的数据
Function<T, R> T R apply(T t); 接收T类型的参数,返回R类型的数据
BiFunction<T, U, R> T, U R apply(T t, U u) 接收T类型和U类型的两个参数,返回R类型的结果

总结:通过对上述的函数式接口的定义和调用方式,来达到对函数式接口的认识,也希望这篇文档能帮助读者了解lambda表达式和函数式接口。理解有误的地方麻烦指正,谢谢。


 本篇
java.util.function中的函数式接口 java.util.function中的函数式接口
前言:针对与jdk1.8的新特性(流),java.util.function包下的函数式接口的学习是必不可少的。lambda表达式的入参除了普通的入参,大部分都是以lambda表达式作为方法的入参。如{(a, b) -> a + b}
2020-09-07
下一篇 
项目打包成镜像 项目打包成镜像
项目打包成镜像并推送至阿里云的镜像仓库 项目打包成jar包 $ mvn clean package -Dmaven.test.skip=true 打包成功之后,首先还有比较重要的一步,编写Dockerfile ## 运行在openjdk
2020-08-28
  目录