➢ 有且仅有一个抽象方法的接口。
➢ 被 @FunctionalInterface 注解的接口,
接口上添加 @FunctionalInterface 注解意味着该接口只能有一个抽象方法,否则会编译报错
函数式接口更多是为Lambda表达式服务的,所以函数式接口即可以适用于Lambda使用的接口。
Java8 在 java.util.function 包下预定义了大量的函数数式接口供我们使用。其中比较常用的如:
➢ Supplier 接口,供给型接口
➢ Consumer 接口,消费型接口
➢ Predicate 接口,判断型接口
➢ Function 接口,函数型接口
提供者接口,只有一个无参的方法:
Supplier 接口应用场景:
源码:
package java.util.function;
@FunctionalInterface
public interface Supplier<T> {
/**
* 提供指定类型的数据。
*/
T get();
}
案例:
// Supplier 接口,泛型参数是出参类型,不接受参数,但是会提供结果
Supplier<String> supplier = () -> "提供一个结果";
System.out.println(supplier.get());
消费接口,对给定的参数进行消费,无返回结果。接口中提供2️⃣个方法:
Consumer 接口的应用场景:
源码:
package java.util.function;
import java.util.Objects;
@FunctionalInterface
public interface Consumer<T> {
/**
* 将给定数据进行消费的方法。
*/
void accept(T t);
/**
* 将多个Consumer按顺序排列,先执行accept操作,然后执行after的accept操作。
*/
default Consumer<T> andThen(Consumer<? super T> after) {
Objects.requireNonNull(after);
return (T t) -> { accept(t); after.accept(t); };
}
}
案例1:
Consumer<String> consumer = x -> {
System.out.println(x);
};
consumer.accept("接受参数");
案例2:
Consumer<String> first = x -> System.out.println("first:" + x);
Consumer<String> second = x -> System.out.println("second:" + x);
Consumer<String> result = first.andThen(second);
//调用了accept 后,会先执行 first 容器里的代码,再执行 second 容器里的代码
result.accept("Hello");
断言接口,对给定的参数进行判断,返回断言结果。接口中提供5️⃣个方法:
Predicate 接口应用:
源码:
package java.util.function;
import java.util.Objects;
@FunctionalInterface
public interface Predicate<T> {
/**
* 对给定的参数进行判断(判断逻辑由Lambda表达式实现),返回一个布尔值。
*/
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);
}
}
案例1:
Predicate<String> predicate = x -> {
return x == "a";
};
System.out.println(predicate.test("z"));
// false
System.out.println(predicate.test("a"));
// true
System.out.println(predicate.negate().test("a"));
// false
案例2:
Predicate<String> predicate = x -> {
return x == "a";
};
Predicate<String> predicate2 = x -> {
return x == "z";
};
Predicate<String> and = predicate.and(predicate2);
System.out.println(and.test("z"));
// false
Predicate<String> or = predicate.or(predicate2);
System.out.println(or.test("z"));
// true
Predicate<String> a = Predicate.isEqual("a");
Predicate<String> b = Predicate.isEqual("b");
System.out.println(a.or(b).test("a"));
// true
函数接口,将给定参数进行计算后按指定类型返回。接口中提供4️⃣个方法:
Function 接口应用:
源码:
package java.util.function;
import java.util.Objects;
@FunctionalInterface
public interface Function<T, R> {
/**
* 函数
*/
R apply(T t);
/**
* 返回一个组合函数,首先将before函数应用于输入,然后将该函数应用于结果。
*/
default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
Objects.requireNonNull(before);
return (V v) -> apply(before.apply(v));
}
/**
* 返回一个组合函数,首先将该函数应用于输入,然后将after函数应用于结果。
*/
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;
}
}
案例1:
Function<String, String> function1 = x -> {
return "null-" + x;
};
System.out.println(function1.apply("1"));
// null-1
System.out.println(function1.andThen(function1).apply("2"));
// null-null-2
案例2:
Function<String, String> function1 = x -> {
return "null-" + x;
};
Function<String, String> function2 = x -> {
return "non-" + x;
};
System.out.println(function1.andThen(function2).apply("2"));
// non-null-2
System.out.println(function1.compose(function2).apply("2"));
// null-non-2
案例3:
System.out.println(Function.identity().apply("aaaa"));
// aaaa