- Java 8 中的 Stream 是对集合(Collection)对象功能的增强。
- 聚合操作、大批量数据操作
- 与Lambda结合,极大的提高编程效率和程序可读性
- 供串行和并行两种模式
- Stream 的另外一大特点是,数据源本身可以是无限的。
- 流处理的一般过程:数据源(source)→ 数据转换(转换成想要的数据)→执行操作获取想要的结果
- stream的内部不存储数据,它只是抓取数据
- stream也绝不修改底层数据,每次操作都产生一个新的stream
- 不支持下标索引访问
常用流操作
- 流的构成:
- list.stream():list->stream
- list.parallelStream()
- Arrays.stream(new int[]{1,2,3}):array->stream
- IntStream.range(1,3)
- Stream.of(1,2,3):多个字段->stream
- IntStream.concat(stream1,stream2):stream+stream->stream
Intermediate
-
其目的主要是打开流,做出某种程度的数据映射/过滤,然后返回一个新的流,交给下一个操作使用
-
这是一个惰性的操作,需要有terminal后才开始执行
-
多个转换操作只会在 Terminal 操作的时候融合起来,一次循环完成。不会出现多次循环
-
对流排序:stream.sorted((a, b) -> a.getAge() - b.getAge())
-
对流过滤:stream.filter(a -> a.getAge() > 11)、stream.skip()跳过前几个元素
-
对流遍历:stream.peek()
-
对流转换:stream.map()、stream.flatMap()
//把 input Stream 中的层级结构扁平化,就是将流中最底层元素抽出来放到一起
Stream<List<Integer>> listStream=Stream.of(Arrays.asList(2,3,4),Arrays.asList(2,6,4),Arrays.asList(5,3,4));
listStream.flatMap(list->list.stream()).forEach(System.out::println);
Stream<String> stringStream=Stream.of("ddd fdsf dfs fsd fasf dfd","ddd2 321");
stringStream.flatMap(str->Stream.of(str.split(" "))).forEach(System.out::println);
Terminal
-
一个流只能有一个 terminal 操作
-
Terminal 操作的执行,才会真正开始流的遍历
-
对流转换
- stream.collect(Collectors.toList())
- stream.collect(Collectors.toCollection(ArrayList::new));
- stream转换成数组
- stream提取数据后转换成集合
ArrayList<String> nameList=Stream.of(new String[]{"ming","jia","rui"}).map(str->str+"!!")
.collect(Collectors.toCollection(ArrayList::new));
System.out.println(nameList.get(1));
ArrayList<Person> list=new ArrayList<>();
list.add(new Person(1,"ming"));
list.add(new Person(5,"rui"));
list.add(new Person(3,"Tom"));
int[] ages=list.stream()
.mapToInt(Person::getAge)
.filter(age->age>2)
.toArray();
System.out.println(Arrays.toString(ages));
//stream提取数据后转换成集合
List<Integer> list1=new ArrayList<>();
list.stream()
.mapToInt(Person::getAge)
.filter(age->age>2)
.forEach(list1::add);
System.out.println(list1);
- 对流进行聚集
- findFirst
- reduce:把 Stream 元素组合起来,进行滚动运算。以下是其衍生出来的简化方法
- sum
- min
- max
int max=Stream.of(6,10,3,5,7).reduce(Integer.MIN_VALUE,(a,b)->a>b?a:b);
System.out.println(max);
int total=Stream.of(1,3,5,7).reduce(0,(a,b)->a+b);
System.out.println(total);
- 遍历
- forEach():如果用了parallelStream,不能保证顺序
short-circuiting
-
输入一个无限大的数据,但是只返回一个有限长度数据集,或者在有限时间计算出结果
-
findFirst
-
limit
Random random=new Random(10);
int[] nums=random.ints().limit(10).toArray();
Optional
- 尽可能避免 NullPointerException。
- 使用 Optional 代码的可读性更好
- Stream 中的 findAny、max/min、reduce 等方法等返回 Optional 值
https://www.ibm.com/developerworks/cn/java/j-lo-java8streamapi/