本文重点是为了介绍stream,但是在介绍之前我们可以先看一个问题
对于一个数组如何找出其中出现次数最多的数?
public static void main(String[] args) {
Integer[] array = {12, 34, 44, 44, 33, 33, 33, 33};
HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
for (int i = 0; i < array.length; i++) {
int key = array[i];
if (map.containsKey(key)) {
map.replace(key, map.get(key) + 1);
} else {
map.put(key, 1);
}
}
int key = array[0];
for (Entry<Integer, Integer> entry : map.entrySet()) {
if (entry.getValue() > map.get(key)) {
key = entry.getKey();
}
}
return key;
}
public static void main(String[] args) {
Integer[] array = {12, 34, 44, 44, 33, 33, 33, 33};
Integer ss = Stream.of(array).collect(Collectors.groupingBy(Integer::valueOf))
.values()
.stream()
.sorted((a, b) -> b.size() - a.size())
.collect(Collectors.toList()).get(0).get(0);
System.out.println(ss);
}
肉眼可见,使用了stream后,对于数组,集合相关的一些聚合操作会显得更加简洁。对于上述两种方案的性能在此不考虑。
它作为对原始集合操作的增强,在对集合,数组的集合操作上,通过配合lamda,提供了简洁的编码手段。它还提供串行和并行两种方式,对于并行方式能利用如今多核心的优势,加快运算,同时我们又不需要手动编写多线程相关代码。
stream不是一种数据结构,它与运算相关,在下面的参考文章中,把它比作高级的Iterator,我觉得有点道理。对于流里的数据,是单向处理,一次性,处理过了就没了。
从代码上直观感受,stream操作就是一连串的调用,符合我们对流的理解(这种链式调用有点像设计模式中的构造者模式,其它地方也比较常见)
具体来讲,我们对集合,数组进行过滤,映射,排序等这样的操作时,可以考虑用stream
在使用stream的时候,我们一定要搞清楚的一个概念,流的操作分为两种
简单的介绍如何通过数组和集合获取流
collection.stream(); // 集合获取stream
Stream.of(array); // 数组获取stream
对数组进行排序
Integer[] array = {12, 34, 44, 44, 33, 33, 33, 33};
List<Integer> list = Arrays.stream(array).sorted((a, b) -> b-a).collect(Collectors.toList());
System.out.println(list);
当然stream能做的远比这强大,它的intermeditate和terminal都分别提供了丰富的方法,有兴趣的可以继续阅读如下参考文章
Java的Stream流式处理
JAVA 8 ‘::’ 关键字