java8-lambda
Java 8中的Stream API可以让你写出这样的代码:
声明性——更简洁,更易读4.1 流是什么 71
可复合——更灵活
可并行——性能更好
1.方法引用
方法引用主要有三类。
(1) 指向静态方法的方法引用(例如Integer的parseInt方法,写作Integer::parseInt)。你 的 第 一 个
方法引用!
(2) 指 向 任 意 类 型 实 例 方 法 的 方 法 引 用 ( 例 如 String 的 length 方 法 , 写 作
String::length)。
(3) 指向现有对象的实例方法的方法引用(假设你有一个局部变量expensiveTransaction用于存放Transaction类型的对象,它支持实例方法getValue,那么你就可以写expensiveTransaction::getValue)。
2:(arg0,test)->arg0.instanceMethod(test)
ClassName::instanceMethod ClassName是arg0的class
3:test->expr.instanceMethod(test)
axpr::instanceMethod
2.构造函数引用
public class Apple {
private String color;
private int weight;
public Apple(String color, int weight) {
this.color = color;
this.weight = weight;
}
public Apple(String color) {
this.color = color;
}
public Apple(int weight) {
this.weight = weight;
}
public void test() {
Supplier p = Apple::new;
Function p2 = Apple::new;
Function p3 = Apple::new;
BiFunction p4 = Apple::new;
}
}
3.复合方法
Predicate 有negate、 and和or三个默认实现,对应的非,与,或的意思很好理解
Function 有andThen和compose两个默认方法
例如f.andThen(g)就是g(f(x)) f.compose就是f(g(x))
4.内部外部迭代
Streams库的内部迭代可以自动选择一种适合你硬件的数据表示和并行实现。与此相反,一旦通过写for-each而选择了外部迭代,那你基本上就要自己管理所有的并行问题了(自己管理实际上意味着“某个良辰吉日我们会把它并行化”或 “ 开 始 了 关 于 任 务 和synchronized 的 漫 长 而 艰 苦 的 斗 争 ”)
5.使用流
filter predicate 过滤元素
distinct 流所生成元素的hashCode和equals方法实现 筛选各异元素
limit int 截断流
skip int 跳过头几个元素
map function
flatmap function
anyMatch predicate 流中是否有一个元素能匹配给定的谓词
allMatch predicate 它会看看流中的元素是否都能匹配给定的谓词
noneMatch predicate 它可以确保流中没有任何元素与给定的谓词匹配。
findAny void 返回当前流中的任意元素
findFirst void 查找第一个元素
归约
reduce
Optional reduce(BinaryOperator accumulator);
不接受初始值,但是会返回一个Optional对象
T reduce(T identity, BinaryOperator accumulator)
接受两个参数:
一个初始值
一个BinaryOperator来将两个元素结合起来产生一个新值。
U reduce(U identity,BiFunction accumulator,BinaryOperator combiner);
combiner用于并行计算的时候 操作两个结果集的函数
Collect
Collectors.groupingBy Function
Collectors.toList() List
Collectors.counting() long 总和
Collectors.maxBy Optional 最大值
Collectors.summingInt
Collectors.averagingInt 均值
joining() 将对象toString连接
joining(", ") 入参分隔符
public static Collector reducing(U identity,Function super T, ? extends U> mapper,BinaryOperator op)
它需要三个参数。
第一个参数是归约操作的起始值,也是流中没有元素时的返回值.
第二个参数就是转换函数
第三个参数是一个BinaryOperator,将两个项目累积成一个同类型的值。
public static Collector> reducing(BinaryOperator op)
你可以把单参数reducing工厂方法创建的收集器看作三参数方法的特殊情况,它把流中的第一个项目作为起点,把恒等函数(即一个函数仅仅是返回其输入参数)作为一个转换函数。
Stream接口的collect和reduce方法有何不同,因为两种方法通常会获得相同的结果。语义问题在于, reduce方法旨在把两个值结合起来生成一个新值,它是一个不可变的归约。与此相反, collect方法的设计就是要改变容器,从而累积要输出的结果。以错误的语义使用reduce方法还会造成一个实际问题:这个归约过程不能并行工作,因为由多个线程并发修改同一个数据结构可能会破坏List本身。在这种情况下,如果你想要线程安全,就需要每次分配一个新的List,而对象分配又会影响性能。这就是collect方法特别适合表达可变容器上的归约的原因。
groupingBy(f)(其中f是分类函数)实际上是groupingBy(f,Collects.toList())的简便写法
partitioningBy
分区是分组的特殊情况:由一个谓词(返回一个布尔值的函数)作为分类函数。分区函数返回一个布尔值,这意味着得到的分组Map的键类型是Boolean。