Lambda 表达式是如何在java的类型系统中表示的呢?每一个lambda表达式都对应一个类型,通常是接口类型。而“函数式接口”是指仅仅只包含一个抽象方法的 接口,每一个该类型的lambda表达式都会被匹配到这个抽象方法。因为 默认方法 不算抽象方法,所以你也可以给你的函数式接口添加默认方法。
我们可以将lambda表达式当作任意只包含一个抽象方法的接口类型,确保你的接口一定达到这个要求,你只需要给你的接口添加 @FunctionalInterface 注解,编译器如果发现你标注了这个注解的接口有多于一个抽象方法的时候会报错的。
Predicates
Predicates are boolean-valued functions of one argument. The interface contains various default methods for composing predicates to complex logical terms (and, or, negate)
谓词谓词是只有一个参数的布尔型函数。这个接口包含不同的默认方法,将谓词组成复杂的逻辑组合。
public class PredicateTest {
public static void main(String[] args) {
Predicate<String> predicate = (s) -> s.length() > 0;
// 检查给定参数的谓词
Boolean a = predicate.test("foo"); // true
// 逻辑上相反的谓词
Boolean b = predicate.negate().test("foo"); // false
// 引用静态方法
Predicate<Boolean> nonNull = Objects::nonNull;
Predicate<Boolean> isNull = Objects::isNull;
System.out.println(nonNull.test(null)); // false
System.out.println(isNull.test(null)); // true
// 引用普通方法
Predicate<String> isEmpty = String::isEmpty;
Predicate<String> isNotEmpty = isEmpty.negate();
System.out.println(isEmpty.test("")); // true
System.out.println(isNotEmpty.test("")); // false
}
}
Functions
Functions accept one argument and produce a result. Default methods can be used to chain multiple functions together (compose, andThen).
将Function对象应用到输入的参数上,然后返回计算结果
public class FunctionTest {
public static void main(String[] args) {
// toInteger 称作函数对象
// 表示一个方法,接受一个参数,产生一个结果;第一个是入参,第二个是结果
Function<String, Integer> toInteger = Integer::valueOf;
// 返回一个先执行当前函数对象apply方法再执行after函数对象apply方法的函数对象。
Function<String, String> backToString = toInteger.andThen(String::valueOf);
backToString.apply("123"); // "123"
// 这个函数式接口的函数方法是apply, 把函数应用在指定的参数上
// 如果你想把接受一些输入参数并将对输入参数处理过后的结果返回的功能封装到一个方法内,Function接口是一个不错的选择
System.out.println(toInteger.apply("123"));
Function<String, Integer> f1 = (t) -> Integer.valueOf(t) * 10;
System.out.println(f1.apply("3")); // 30
// 返回自身
System.out.println(Function.identity().apply("3")); // 3
// 先执行 apply 在执行andThen
System.out.println(f1.andThen((r) -> String.valueOf(r) + ".....").apply("4")); // 40.....
// 先执行compose里面的函数 再执行本函数的apply
System.out.println(f1.compose((String r) -> r.substring(1)).apply("a5"));
}
}
Suppliers
Suppliers produce a result of a given generic type. Unlike Functions, Suppliers don't accept arguments.
supplier 产生指定类型的一个结果。不同于function,supplier 不接受参数。 类似 一个使用默认构造器的工厂方法。public class SupplierTest {
public static void main(String[] args) {
Supplier<Person> personSupplier = Person::new;
Person persion = personSupplier.get(); // new Person
System.out.println(persion); // Person [firstName=null, lastName=null]
}
}
Consumers
Consumers represents operations to be performed on a single input argument.
consumer 表示作用在一个入参上的操作,没有返回值。例子 (星球大战)
public class ConsumerTest {
public static void main(String[] args) {
Consumer<Person> greeter = (p) -> System.out.println("Hello, " + p.firstName);
greeter.accept(new Person("Luke", "Skywalker"));
}
}
Comparators
Comparators are well known from older versions of Java. Java 8 adds various default methods to the interface.
public class ComparatorTest {
public static void test() {
List<String> names = Arrays.asList("peter", "anna", "mike", "xenia");
Collections.sort(names, new Comparator<String>() {
@Override
public int compare(String a, String b) {
return b.compareTo(a);
}
});
Collections.sort(names, (String a, String b) -> {
return b.compareTo(a);
});
Collections.sort(names, (String a, String b) -> b.compareTo(a));
Comparator<Person> comparator = (p1, p2) -> p1.firstName.compareTo(p2.firstName);
Person p1 = new Person("John", "Doe");
Person p2 = new Person("Alice", "Wonderland");
comparator.compare(p1, p2); // > 0
comparator.reversed().compare(p1, p2); // < 0
}
}
Optional 看上去没什么用,和NPE相关的。参考 http://www.oracle.com/technetwork/articles/java/java8-optional-2175753.html
Optional 不是函数是接口,这是个用来防止NullPointerException异常的辅助类型,这是下一届中将要用到的重要概念,现在先简单的看看这个接口能干什么:
Optional 被定义为一个简单的容器,其值可能是null或者不是null。在Java 8之前一般某个函数应该返回非空对象但是偶尔却可能返回了null,而在Java 8中,不推荐你返回null而是返回Optional。
Optional<String> optional = Optional.of("bam");
optional.isPresent(); // true
optional.get(); // "bam"
optional.orElse("fallback"); // "bam"
optional.ifPresent((s) -> System.out.println(s.charAt(0))); // "b"