目录
概述
Lambda表达式的使用前提是函数式接口,为了便利Lambda表达式的使用,Java8提供了内置的四大函数式接口,四大函数式接口满足了程序设计的大部分情况,省去了使用Lambda表达式时写函数式接口的步骤。
四大函数式接口分别为:Consumer、Supplier、Function、Predicate,参数及返回值类型如下表所示:
函数式接口 | 抽象方法 | 传入参数类型 | 返回值类型 |
---|---|---|---|
Consumer | accept | T | void |
Supplier | get | 无 | T |
Function | apply | T | R |
Predicate | test | T | boolean |
内容
Consumer
源码
@FunctionalInterface
public interface Consumer<T> {
void accept(T t);
default Consumer<T> andThen(Consumer<? super T> after) {
Objects.requireNonNull(after);
return (T t) -> { accept(t); after.accept(t); };
}
}
分析
Consumer有函数式接口的注解“@FunctionalInterface”,说明Consumer需要满足函数式接口的要求,要求具体见初识函数式接口;
Consumer顾名思义是一个消费者,用于消费T类型的对象,并没有产生返回值;
accept方法
抽象方法accept()没有返回值类型,用于处理T类型对象;
andThen方法
指定调用完当前Consumer方法后是否还需要调用其它Consumer的accept()方法的default方法andThen()。
示例代码
通过Consumer接口来处理Person类型的数据,分别输出Person的姓名和年龄。
public class ConsumerDemo {
public static void main(String[] args) {
Consumer<Person> con1 = (person) -> System.out.println(person.getName());
Consumer<Person> con2 = (person) -> System.out.println(person.getAge());
Person per = new Person("张三", 20);
con1.accept(per);
con1.andThen(con2).accept(per);
con2.andThen(con1).accept(per);
}
}
运行结果
张三
张三
20
20
张三
注意
调用andThen()方法的con2和con1处理的数据是同一个数据,都是通过accept()方法接收到的per,只是在处理方法上有所不同。
Supplier
源码
@FunctionalInterface
public interface Supplier<T> {
T get();
}
分析
Supplier也满足函数式接口的定义,有“@FunctionalInterface”注解;
Supplier顾名思义是一个提供者,它不需要传入任何的参数,就可以获得提供一个T类型的对象;
get方法
Supplier仅有一个用于提供T类型对象的抽象方法get()。
示例代码
中国的年满18岁的程序员会分配到国家提供的女朋友。
public class SupplierDemo {
public static void main(String[] args) {
Supplier<Person> china = () -> new Person("girl", 18);
Person programmer = new Person("程序员", 18);
programmer.setFriend(china.get());
System.out.println(programmer.toString());
}
}
运行结果
我覆写了toString()方法,结果如下:
name: 程序员
age: 18
friend: girl
Function
源码
@FunctionalInterface
public interface Function<T, R> {
R apply(T t);
default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
Objects.requireNonNull(before);
return (V v) -> apply(before.apply(v));
}
default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
Objects.requireNonNull(after);
return (T t) -> after.apply(apply(t));
}
static <T> Function<T, T> identity() {
return t -> t;
}
}
分析
Function满足函数式接口的定义,有“@FunctionalInterface”注解,它的具体方法如下:
apply方法
Function顾名思义是一个函数,经常被作为一个中间函数调用,所以有一个含有输入和输出的抽象方法apply(),apply()用于处理T类型的对象,返回R类型的结果;
andThen方法
Function有一个Consumer中也有的功能相同的默认方法andThen(),用于指定当前的Function的apply()方法执行完毕后是否需要执行的下一个Function。
compose方法
Function中compose()方法功能与andThen()类似。顺序不同,compose() 先执行参数,再执行调用者。
identity方法
Function的identity()是一个用于返回当前正在执行的方法的一个静态方法。
示例代码
public class FunctionDemo {
public static void main(String[] args) {
Function<Person, Person> dating = (s) -> { // 一个交友的方法
s.setFriend(new Person("张三", 20));
return s;
};
Function<Person, Person> breakUp = (s) -> { // 一个和朋友断交的方法
s.setFriend(new Person("", 0));
return s;
};
Person person = new Person("李四", 25);
dating.apply(person); // 测试apply() -> 让李四和张三交朋友
System.out.println(person.toString());
System.out.println("-------------------------");
person = new Person("李四", 25); // 初始化李四
dating.andThen(breakUp).apply(person); // 测试andThen() -> 让李四先交朋友再断交
System.out.println(person.toString());
System.out.println("-------------------------");
person = new Person("李四", 25); // 初始化李四
dating.compose(breakUp).apply(person); // 测试andThen() -> 让李四先断交再交朋友
System.out.println(person.toString());
System.out.println("-------------------------");
System.out.println(Function.identity().apply(person)); // 测试当前正在执行的方法
}
}
运行结果
name: 李四
age: 25
friend: 张三
-------------------------
name: 李四
age: 25
friend:
-------------------------
name: 李四
age: 25
friend: 张三
-------------------------
name: 李四
age: 25
friend: 张三
注意
- Function中的四个方法,除了抽象方法apply(),其余都能返回一个Function类型的对象用于迭代;
- andThen()和compose()功能相同,顺序相反。
Predicate
源码
@FunctionalInterface
public interface Predicate<T> {
boolean test(T t);
default Predicate<T> and(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) && other.test(t);
}
default Predicate<T> negate() {
return (t) -> !test(t);
}
default Predicate<T> or(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) || other.test(t);
}
static <T> Predicate<T> isEqual(Object targetRef) {
return (null == targetRef)
? Objects::isNull
: object -> targetRef.equals(object);
}
}
分析
Predicate满足函数式接口的定义,有“@FunctionalInterface”注解,它的具体方法如下:
test方法
抽象方法test(),用于处理T类型的对象,并且返回一个布尔型的值表达处理的结果。
and方法
默认方法and(),与短路与“&&”运算符类似,传入一个Predicate对象,返回一个Predicate类型对象,用于连接两个Predicate类型的对象,连接后全真才为真。
or方法
默认方法or(),与短路运算符“||”类似,传入一个Predicate对象,返回一个Predicate类型对象,用于连接两个Predicate类型的对象,连接后有真即为真。
negate方法
默认方法negate(),与关系运算符“!”类似,没有传入参数,返回一个Predicate类型对象,用于取反操作。
isEqual方法
静态方法isEqual(),接收一个Object类型的对象,返回一个Predicate类型对象,用于判断第一个test的方法与第二个test方法是否相同。
示例代码
public class PredicateDemo {
public static void main(String[] args) {
Predicate<String> judge = (str) -> str.equals("皮一下就很开心");
Predicate<String> p = (s) -> s.equals("皮");
String str = "皮一下就很开心";
System.out.println(judge.test(str));
System.out.println(judge.negate().test(str)); //!true
System.out.println(judge.and(p).test(str)); //false&&true
System.out.println(judge.or(p).test(str)); //false||true
}
}
运行结果
true
false
false
true