java8

58 阅读2分钟

zhuanlan.zhihu.com/p/33253953 www.cnblogs.com/IcanFixIt/p… juejin.im/post/597829…

判断一个操作是惰性求值还是及早求值很简单:只需看它的返回值。如果返回值是 Stream, 那么是惰性求值;如果返回值是另一个值或为空,那么就是及早求值。使用这些操作的理 想方式就是形成一个惰性求值的链,最后用一个及早求值的操作返回想要的结果,这正是 它的合理之处。计数的示例也是这样运行的,但这只是最简单的情况:只含两步操作。 整个过程和建造者模式有共通之处。建造者模式使用一系列操作设置属性和配置,最后调 用一个 build 方法,这时,对象才被真正创建。 读者一定会问:“为什么要区分惰性求值和及早求值?”只有在对需要什么样的结果和操 作有了更多了解之后,才能更有效率地进行计算。例如,如果要找出大于 10 的第一个数 字,那么并不需要和所有元素去做比较,只要找出第一个匹配的元素就够了。这也意味着 可以在集合类上级联多种操作,但迭代只需一次。

接口参数返回类型示例
PredicateTboolean这张唱片已经发行了吗
ConsumerTvoid输出一个值
Function<T,R>TR获得 Artist 对象的名字
SupplierNoneT工厂方法
UnaryOperatorTT逻辑非(!)
BinaryOperator(T, T)T求两个数的乘积(*)

函数式接口是只有一个抽象方法的接口,用作 Lambda 表达式的类型。 函数式接口可以加上@FunctionalInterface注解,使编译器检查接口是否符合函数式接口规范,函数式接口有且仅有一个抽象方法,可以包含多个默认方法。

以函数式接口Predicate为例,可以由抽象方法 boolean test(T t)确定该函数式接口的参数为T,返回值为boolean

@FunctionalInterface
public interface Predicate<T> {
    /**
     * Evaluates this predicate on the given argument.
     *
     * @param t the input argument
     * @return {@code true} if the input argument matches the predicate,
     * otherwise {@code false}
     */
    boolean test(T t);

lambda表达式是一段可以传递的代码,它的核心思想是将面向对象中的传递数据变成传递行为

java 8之前启动线程是通过匿名类的方式,设计匿名内部类的目的,就是为了方便 Java 程序员将代码作为数据传递。但是缺点在于不够简洁,可读性差。 lambda也是将代码传递给run方法,非常简洁,这也就解释了为什么函数式接口只能有一个抽象方法,因为lambda无法指定目标方法

	new Thread(new Runnable() {
		@Override
		public void run() {
			System.out.println("start thread by anonymous class.");
		}
	}).start();
	
	new Thread(() -> System.out.println("start thread by lambda.")).start();