物竞天择,适者生存
java8 对于程序员的主要好处在于,他提供更多的编程工具和概念,能以更快,尤其是更简洁,更易于维护的方式解决新的或 者现有的编程问题。
由于这些特性,他主要运用于对性能要求没那么高,但是对安全性,可维护性要求较高的场景。
流是一系列数据项,一次只能生成一项。程序可以从输入流一项一项读取数据项,然后再把数据项一项一项写入到输出流,一个程序的输出流和可能是另一个程序的输入流。
Steam
这样做的好处在于
①:可以在更高的抽象层次上写java程序了,思路变成把一个流变成另外一个流,而不是一次只能处理一个项目。
②:java8 中可以一次将输入的几个不相关的部分拿到不同的CPU内核,分别执行你的Stream操作流水线。
java8 增加了将方法(你的代码:方法或者函数)作为参数传递给另一个方法的能力,将其称之为行为参数化。Stream API就是构建在通过传递代码使操作行为实现参数化的思想上。当把compareUsingCustomerId传进去,你就把sort行为参数化了。
写代码时不能访问共享的可变数据,这些函数被称为“无状态函数”,“纯函数”,“无副作用函数”。
前面说的并行,只有假定代码的多个副本可以独立的工作才能进行,但是要访问的是一个共享变量就行不通了。
没有共享的可变数据与将代码传递给其他方法的能力,这两个要点,是函数式编程范式的基石;
??
与此相反,在命令式编程
范式中,你写的程序则是一系列改变状态的指令。“不能有共享的可变数据”的要求意味着,一
个方法是可以通过它将参数值转换为结果的方式完全描述的;换句话说,它的行为就像一个数学
函数,没有可见的副作用
语言需要不断的跟进硬件的更新和程序员的期待。
编程语言的整个目的就是操作值。
将二等公民(类,方法)转化为一等公民(值),在运行中传递方法,将方法转化为一等公民。
第一个新特性-方法引用:
lambda-匿名函数:函数式编程风格,即为编写把函数作为一等值来传递的程序。
代码示例:
//方法编写
//参与比较的方法
public static boolean isGreenApple(Apple apple){
return "green".equals(apple.getColor());
}
public static boolean isHeavyApple(Apple apple){
return apple.getWeight()>150;
}
//谓词<操纵的类>
public static List filterApples(List inventory,Predicate p){
List result = new ArrayList<>();
for(Apple apple:inventory){
if(p.test(apple))
result.add(apple);
}
return result;
}
//调用
List heavyApples2 = filterApples(inventory,FilteringApples::isHeavyApple);
System.out.println(heavyApples2);
List greenApples2 = filterApples(inventory,FilteringApples::isGreenApple);
System.out.println(greenApples2);
把方法作为值传递很方便,但是这种方法适用性太窄,写一堆太麻烦,所以引入匿名函数或者lambda。
代码示例:
List greenApples3 = filterApples(inventory,(Apple a)->"green".equals(a.getColor()));
System.out.println(greenApples3);
List heavyApples3 = filterApples(inventory,(Apple a)->a.getWeight()>150);
System.out.println(heavyApples3);
lambda 适用于短小的语句,当语句多于几行时改用类。
为了更好的利用并行,Stream登场。
基于集合处理时的套路和晦涩: 化外部迭代------>内部迭代,Stream API 代替 Collection API
基于集合难于利用多核: Stream API 代替 Collection API
这么做的原因:
①:有许多反复出现的数据处理模式,如上例和数据库查询语言里熟悉的操作,如果库里有这些会非常方便:根据标 准筛选数据,提取数据,或给数据分组。
②:这些操作往往是并行化的,将一个任务分成多个部分,n个核负责n个部分,处理完之后再合并结果。
List heavyApples =
inventory.parallelStream().filter((Apple a) -> a.getWeight() > 150) .collect(toList());
System.out.println(heavyApples);
??
default 关键字 可以实现接口中的默认方法,即当接口增添新方法时,实现类可不必实现接口中新增加的方法。
例如:
扩充List接口,为其添加sort()方法,实现类可直接调用默认方法而不用实现它。
default void sort(Comparator c){
Collections.sort(this,c);
}
前面说过两个核心思想:
① 讲方法和lambda作为一等值
② 在没有可变共享变量的前提下,函数或者方法可以安全、有效的并行执行。
Stream API 运用到了这两种思想
还有其他思想:
① 避免使用null,使用更多的描述性数据类型代替null。
② (结构)模式匹配:以后章节会详细说明