内置的函数式接口
2023-04-15 11:14
3572
0
JDK 1.8 API 包含了很多内置的函数式接口。其中就包括我们在老版本中经常见到的 Comparator 和 Runnable,Java 8 为他们都添加了 @FunctionalInterface 注解,以用来支持 Lambda 表达式。
例如我们旧版本的Jdk中常用的 Comparator 和 Runnable 外,还有一些新的函数式接口,可以通过函数注解实现Lamdba支持,它们很多都借鉴于知名的 Google Guava (opens new window)库。
即使你已经熟悉这个类库,也应该密切关注那些接口是如何通过一些有用的方法扩展来扩展的:
#1. Predicate 断言
Predicate 是一个可以指定入参类型,并返回 boolean 值的函数式接口。它内部提供了一些带有默认实现的方法,可以 被用来组合一个复杂的逻辑判断(and, or, negate):
@Test public void test11() { Predicate<String> predicate = (s) -> s.length() > 0;
boolean foo0 = predicate.test("foo"); // true boolean foo1 = predicate.negate().test("foo"); // negate否定相当于!true Predicate<Boolean> nonNull = Objects::nonNull; Predicate<Boolean> isNull = Objects::isNull; Predicate<String> isEmpty = String::isEmpty; Predicate<String> isNotEmpty = isEmpty.negate();
}
@小傅哥: 代码已经复制到剪贴板
#2. Functions
Function 函数式接口的作用是,我们可以为其提供一个原料,他给生产一个最终的产品。通过它提供的默认方法,组合,链行处理(compose, andThen):
@Test public void test12() { Function<String, Integer> toInteger = Integer::valueOf; //转Integer Function<String, String> backToString = toInteger.andThen(String::valueOf); //转String Function<String, String> afterToStartsWith = backToString.andThen(new Something()::startsWith); //截取第一位 String apply = afterToStartsWith.apply("123");// "123" System.out.println(apply); }
@小傅哥: 代码已经复制到剪贴板
#3. Suppliers
Supplier 与 Function 不同,它不接受入参,直接为我们生产一个指定的结果,有点像生产者模式:
@Test public void test13() { Supplier<Person> personSupplier0 = Person::new; personSupplier0.get(); // new Person Supplier<String> personSupplier1 = Something::test01; //这个test方法是静态的,且无入参 personSupplier1.get(); // hi
Supplier<String> personSupplier2 = new Something()::test02;
}
@小傅哥: 代码已经复制到剪贴板
#4. Consumers
对于 Consumer,我们需要提供入参,用来被消费,如下面这段示例代码:
@Test public void test14() { // 参照物,方便知道下面的Lamdba表达式写法 Consumer<Person> greeter01 = new Consumer<Person>() { @Override public void accept(Person p) { System.out.println("Hello, " + p.firstName); } }; Consumer<Person> greeter02 = (p) -> System.out.println("Hello, " + p.firstName); greeter02.accept(new Person("Luke", "Skywalker")); //Hello, Luke Consumer<Person> greeter03 = new MyConsumer<Person>()::accept; // 也可以通过定义类和方法的方式去调用,这样才是实际开发的姿势 greeter03.accept(new Person("Luke", "Skywalker")); //Hello, Luke }
@小傅哥: 代码已经复制到剪贴板
#5. Comparators
Comparator 在 Java 8 之前是使用比较普遍的。Java 8 中除了将其升级成了函数式接口,还为它拓展了一些默认方法:
@Test
public void test15(){
Comparator<Person> comparator01 = (p1, p2) -> p1.firstName.compareTo(p2.firstName);
Comparator<Person> comparator02 = Comparator.comparing(p -> p.firstName); //等同于上面的方式
Person p1 = new Person("John", "Doe");
Person p2 = new Person("Alice", "Wonderland");
comparator01.compare(p1, p2); // > 0
comparator02.reversed().compare(p1, p2); // < 0
}
全部评论