所有的函数式接口实现类,都可以用 lambda 表达式来简化书写,关注实现本身
Predicate
对应常见操作:stream().filter()
基础逻辑关系
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public class GetEvenNumber {
public static void main(String[] args) { List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6); System.out.println(findEvenResult(list)); }
public static List<Integer> findEvenResult(List<Integer> originalData) { Predicate<Integer> even = num -> num % 2 == 0; return originalData.stream() .filter(even) .collect(Collectors.toList()); } }
|
组合逻辑关系
下次再进行逻辑组合就不需要两次 filter 了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public class GetEvenNumber {
public static void main(String[] args) { List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6); System.out.println(findEvenAndGreaterThanFiveResult(list)); }
public static List<Integer> findEvenAndGreaterThanFiveResult(List<Integer> originalData) { Predicate<Integer> even = num -> num % 2 == 0; Predicate<Integer> greaterThanFive = num -> num > 5; return originalData.stream() .filter(even.and(greaterThanFive)) .collect(Collectors.toList()); } }
|
同理可以适用于 or 逻辑关系操作
注意 and 和 or 都是会直接断路的操作
等价于 && 和 ||
逻辑取反
1 2 3 4 5 6 7
| public static List<Integer> findOddResult(List<Integer> originalData) { Predicate<Integer> even = num -> num % 2 == 0; Predicate<Integer> odd = even.negate(); return originalData.stream() .filter(odd) .collect(Collectors.toList()); }
|
直接判断是否相等
Predicate 这个函数式接口中提供了一个静态方法用于直接获取 Predicate 断言
1 2 3 4 5 6 7
| public static Integer findEqFive(List<Integer> originalData) { Predicate<Integer> equalFive = Predicate.isEqual(5); Optional<Integer> first = originalData.stream() .filter(equalFive) .findFirst(); return first.orElse(null); }
|
源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| @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); } }
|
Function
对应常见应用场景:stream().map()
一个输入一个输出
1 2 3 4
| public String toUpperCase(String s) { Function<String, String> upper = str -> str.toUpperCase(Locale.ROOT); return upper.apply(s); }
|
compose
执行当前函数之前,先执行指定的函数
1 2 3 4 5
| public String plusFiveAndToString(Integer i){ Function<Integer, Integer> plusFive = num -> num + 5; Function<Integer, String> toString = String::valueOf; return toString.compose(plusFive).apply(i); }
|
andThen
执行当前函数之后,再执行指定的函数
1 2 3 4 5
| public Integer toIntAndPlusFive(String s) { Function<String, Integer> toInt = Integer::parseInt; Function<Integer, Integer> plusFive = num -> num + 5; return toInt.andThen(plusFive).apply(s); }
|
Identity
返回输入,最常用于我们在 reduce 的时候 Collectors.toMap() 中
我们假设输入的string中每一个开头的字符都不一样,现在想统计对应的映射关系(只是模拟)
1 2 3 4
| public Map<Character, String> getFirstCharAndStrMap(List<String> stringList) { return stringList.stream() .collect(Collectors.toMap(str -> str.charAt(0), Function.identity())); }
|
BiFunction
和 Function 差不多类似
只有 apply 以及 andThen 方法
常见的使用场景:stream().reduce()
Supplier
不接受参数但是返回结果
常用于懒加载等场景
1 2 3 4 5 6
| public class RandomSupplier { public Integer getRandomInt(){ Supplier<Integer> randomSupplier = () -> new Random().nextInt(100); return randomSupplier.get(); } }
|
Consumer
和 Supplier 相对应
只接收参数但是不返回结果
比较常见的场景是:stream().foreach()
Comparator
常见的使用场景:list.sort()
传入 Comparator