类型 | 接口 | 参数 | 返回值 | 描述 |
---|---|---|---|---|
供给型接口 | Supplier<T> | None | T | 没有输入,返回一个对象T |
功能型函数式接口 | Function<T, R> | T | R | 对象转换,T->R |
消费型接口 | Consumer<T> | T | void | 改变对象T内部属性的值 |
断言型接口 | Predicate<T> | T | boolean | 进行逻辑判断,返回boolean值 |
函数式接口特点
1、三种方法
- 唯一的抽象方法
- 使用default定义普通方法(默认方法),通过对象调用。
- 使用static定义静态方法,通过接口名调用。
2、一个新注解@FunctionInterface
如果某一个接口就是为了函数式接口而生的,使用注解@FunctionalInterface告诉编译器这是一个函数式接口,明确这个函数中只有一个抽象方法,当你尝试在接口中编写多个抽象方法的时候编译器将不允许,但是可以有多个非抽象方法。
不过Object类的方法可以定义为抽象方法,因为接口的实现类一定是Object的子类。
二、Supplier供给型接口
Supplier无入参,有返回结果T
@FunctionalInterface
public interface Supplier<T> {
//返回T
T get();
}
Supplier实例:
Supplier<String> supplier = ()-> "Hello World!";
Supplier<String> supplier = ()-> new User();
二、Function功能型函数式接口
Function接口 接受一个输入参数T,返回一个结果R。
@FunctionalInterface
public interface Function<T, R> {
// 接受输入参数,返回一个结果。
R apply(T t);
// 返回一个 先执行before函数对象apply方法,再执行当前函数对象apply方法的 函数对象。
default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
Objects.requireNonNull(before);
return (V v) -> apply(before.apply(v));
}
// 返回一个 先执行当前函数对象apply方法, 再执行after函数对象apply方法的 函数对象。
// 和compose相反
default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
Objects.requireNonNull(after);
return (T t) -> after.apply(apply(t));
}
// 返回一个执行了apply()方法之后只会返回输入参数的函数对象。
static <T> Function<T, T> identity() {
return t -> t;
}
}
Function实例:
public static Integer composeTest(int value, Function<Integer, Integer> function1, Function<Integer, Integer> function2){
return function1.compose(function2).apply(value);
}
public static Integer andThenTest(int value, Function<Integer, Integer> function1, Function<Integer, Integer> function2){
return function1.andThen(function2).apply(value);
}
public static void main(String[] args) {
System.out.println(composeTest(2, val -> val * 5, val -> val + 3)); //25
System.out.println(andThenTest(2, val -> val * 5, val -> val + 3)); //13
}
三:Consumer消费型接口
一个接受单个输入参数并且不返回结果的操作。 与大多数其他函数接口不同, Consumer接口期望通过副作用进行操作。
@FunctionalInterface
public interface Consumer<T> {
//对给定的参数执行此操作
void accept(T t);
//andThen可以实现消费两次。消费一次后,继续消费一次
default Consumer<T> andThen(Consumer<? super T> after) {
Objects.requireNonNull(after);
return (T t) -> { accept(t); after.accept(t); };
}
}
Consumer实例:
pair-> pair.setFrist(20);
四:Predicate断言型接口
Predicate常用于集合的过滤,得到一个新的集合
@FunctionalInterface
public interface Predicate<T> {
//进行某些逻辑判断并返回一个boolean值
boolean test(T t);
//and方法接收一个Predicate类型,也就是将传入的条件和当前条件以并且的关系过滤数据。
default Predicate<T> and(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) && other.test(t);
}
//negate就是将当前条件取反
default Predicate<T> negate() {
return (t) -> !test(t);
}
//or方法同样接收一个Predicate类型,将传入的条件和当前的条件以或者的关系过滤数据
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实例:
public static List<Integer> andTest(List<Integer> list, Predicate<Integer> p1, Predicate<Integer> p2) {
return list.stream().filter(p1.and(p2)).collect(Collectors.toList());
}
public static List<Integer> orTest(List<Integer> list, Predicate<Integer> p1, Predicate<Integer> p2) {
return list.stream().filter(p1.or(p2)).collect(Collectors.toList());
}
public static List<Integer> negateTest(List<Integer> list, Predicate<Integer> p) {
return list.stream().filter(p.negate()).collect(Collectors.toList());
}
public static void main(String[] args) {
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
List<Integer> result;
//大于5并且是偶数
result = andTest(list, integer -> integer > 5, integer1 -> integer1 % 2 == 0);
result.forEach(System.out::println);//6 8 10
System.out.println("-------");
//大于5或者是偶数
result = orTest(list, integer -> integer > 5, integer1 -> integer1 % 2 == 0);
result.forEach(System.out::println);//2 4 6 7 8 9 10
System.out.println("-------");
//条件取反
result = negateTest(list, integer2 -> integer2 > 5);
result.forEach(System.out::println);// 1 2 3 4 5
System.out.println("-------");
}