一 .前言
Java 流这个特性已经出来很久了 , 可以大大的减少我们的代码 , 而且并行处理可以在某些场景下使用多个处理器核心可以大大的提高性能.
不过 Stream 语法新手使用起来还是会有一定的难度 , 这一篇文档由浅到深看一下这个特性.
这是开篇 , 只记录之前梳理的用法 , 下一篇来看源码 , 记得收藏!!!
Stream 的特点
- Stream 不是集合 , 也不是数据结构 , 不可以保存数据
- Stream 有点类似于高级 的 Iterator , 可以用于算法和计算
- 不同于迭代器 , Stream 可以并行化操作 , 数据被分为很多段 , 在不同的线程中进行处理
- 数据源、零个或多个中间操作 ( intermediate ) 以及零个或一个终端操作 (terminal )
- 所有中间操作都是惰性的 , 在管道开始工作之前,任何操作都不会产生任何效果
- 终端操作有点像水龙头 , 开启了水龙头后 , 水才会流动 , 中间操作才会执行
二. 基础知识
2.1 结构运算
2.1.1 双冒号运算
双冒号运算就是将方法当成参数传递给需要的方法 ( Stream ) , 即为方法引用
案例一 : 基础用法
x -> System.out.println(x)
// ------------
System.out::println
案例二 : 复杂用法
for (String item: list) {
AcceptMethod.printValur(item);
}
//------------------
list.faorEach(AcceptMethod::printValur);
2.2 流的创建
2.2.1 集合和数组工具
基础案例
// Collection 工具
Collection.stream () : list.stream();
Stream.<String>builder().add("a").add("b").add("c").build();
Stream.of("a", "b", "c")
Stream.generate(() -> "element").limit(10);
Stream.iterate(40, n -> n + 2).limit(20);
创建一个整数流
IntStream.rangeClosed(1, 100).reduce(0, Integer::sum);
IntStream.rangeClosed(1, 100).parallel().reduce(0, Integer::sum);
// 其他的基本类型案例
LongStream.rangeClosed(1, 3);
创建一个并行流
// API :
Stream<E> parallelStream()
// 案例 :
Collection.parallelStream ()
listOfNumbers.parallelStream().reduce(5, Integer::sum);
listOfNumbers.parallelStream().forEach(number ->
System.out.println(number + " " + Thread.currentThread().getName())
);
数组创建流
Arrays.stream(intArray).reduce(0, Integer::sum);
Arrays.stream(intArray).parallel().reduce(0, Integer::sum);
Arrays.stream(integerArray).reduce(0, Integer::sum);
Arrays.stream(integerArray).parallel().reduce(0, Integer::sum);
合并流
// API : 组合2个 Streams
<T> Stream<T> concat(Stream<? extends T> a, Stream<? extends T> b)
// 案例
Stream<Integer> stream1 = Stream.of(1, 3, 5);
Stream<Integer> stream2 = Stream.of(2, 4, 6);
Stream<Integer> resultingStream = Stream.concat(stream1, stream2);
// 案例 : 合并三个
Stream.concat(Stream.concat(stream1, stream2), stream3);
// 案例 : stream of 合并流
Stream.of(stream1, stream2, stream3, stream4)
其他的案例
// 静态工厂
1. Java.util.stream.IntStream.range ( )
2. Java.nio.file.Files.walk ( )
// 手动创建
1. java.util.Spliterator
2. Random.ints()
3. BitSet.stream()
4. Pattern.splitAsStream(java.lang.CharSequence)
5. JarFile.stream()
// java.io.BufferedReader.lines()
Files.lines(path, Charset.forName("UTF-8"));
Files.lines(path);
补充
分割流案例
2.3 流的操作
一个流可以有多个 intermediate 操作 , 和一个 Terminal 操作 , 当 Terminal 执行完成后, 流就结束了
2.3.1 流的 Intermediate 操作
map : 元素映射
// API :
<R> Stream<R> map(Function<? super T, ? extends R> mapper)
// Map 传入方法函数 , Map 返回的是一个 object
books.stream().filter(e -> "Effective Java".equals(e.getValue())).map(Map.Entry::getKey).findFirst();
wordList.stream().map(String::toUpperCase).collect(Collectors.toList());
Stream.of(1, 2, 3).map(n -> n + 1).collect(Collectors.toList());
nums.stream().map( n -> n * n ).collect (Collectors.toList());
flatMap
// flatMap 返回的是一个 Stream
Stream<List<String>> namesOriginalList = Stream.of(
Arrays.asList("Pankaj"),
Arrays.asList("David", "Lisa"),
Arrays.asList("Amit"));
//flat the stream from List<String> to String stream
Stream<String> flatStream = namesOriginalList
.flatMap(strList -> strList.stream());
flatStream.forEach(System.out::println);
mapToXXX
<