Java8提供了Stream(流)处理集合的关键抽象概念,它可以对集合进行的操作,可以执行非常复杂的查找、过滤和映射数据等操作。Stream API 借助于同样新出现的Lambda表达式,极大的提高编程效率和程序可读性。
1.Java Stream vs Collection
我们列出流相比于Collection的不同的特征:
- 不是数据结构
- 需要用lambdas表达式
- 不能用下标访问
- 可以容易的被聚合为数组或者列表
- 懒访问支持
- 可并行
英文表述如下:
- Not a data structure
- Designed for lambdas
- Do not support indexed access
- Can easily be aggregated as arrays or lists
- Lazy access supported
- Parallelizable
2.创建流
2.1 Stream.of()
代码语言:javascript复制Stream<Integer> stream = Stream.of(1,2,3,4,5,6,7,8,9);
stream.forEach(p -> System.out.println(p));
2.2. Stream.of(array)
代码语言:javascript复制 Stream<Integer> stream = Stream.of( new Integer[]{1,2,3,4,5,6,7,8,9} );
stream.forEach(p -> System.out.println(p));
2.3. List.stream()
代码语言:javascript复制 List<Integer> list = new ArrayList<Integer>();
for(int i = 1; i< 10; i ){
list.add(i);
}
Stream<Integer> stream = list.stream();
stream.forEach(p -> System.out.println(p));
2.4. Stream.generate() or Stream.iterate()
代码语言:javascript复制 Stream<Integer> randomNumbers = Stream
.generate(() -> (new Random()).nextInt(100));
randomNumbers.limit(20)
.forEach(System.out::println);
2.5. Stream of String chars or tokens
代码语言:javascript复制 IntStream stream = "12345_abcdefg".chars();
stream.forEach(p -> System.out.println(p));
//OR
Stream<String> stream = Stream.of("A$B$C".split("\$"));
stream.forEach(p -> System.out.println(p));
3. Stream Collectors
在执行过中间操作之后,我们会用stream的Collector方法收集处理的元素到集合中。
3.1 收集流元素到列表(List)
代码语言:javascript复制 List<Integer> list = new ArrayList<Integer>();
for(int i = 1; i< 10; i ){
list.add(i);
}
Stream<Integer> stream = list.stream();
List<Integer> evenNumbersList = stream.filter(i -> i%2 == 0)
.collect(Collectors.toList());
System.out.print(evenNumbersList);
3.2 收集流元素到数组(Array)
代码语言:javascript复制Stream<Integer> stream = list.stream();
Integer[] evenNumbersArr = stream.filter(i -> i%2 == 0).toArray(Integer[]::new);
你也可以收集流到Set, Map 等中。
4.流操作
先准备一个列表数据
代码语言:javascript复制List<String> memberNames = new ArrayList<>();
memberNames.add("Amitabh");
memberNames.add("Shekhar");
memberNames.add("Aman");
memberNames.add("Rahul");
memberNames.add("Shahrukh");
memberNames.add("Salman");
memberNames.add("Yana");
memberNames.add("Lokesh");
4.1 中间操作
中间操作返回一个流,所以我们可以在一行关联多个方法。
4.1.1. Stream.filter()
代码语言:javascript复制memberNames.stream().filter((s) -> s.startsWith("A"))
.forEach(System.out::println);
输出;
代码语言:javascript复制Amitabh
Aman
4.1.2. Stream.map()
map中间操作通过给出函数转换流中的每个元素为另一个对象
代码语言:javascript复制 memberNames.stream().filter((s) -> s.startsWith("A"))
.map(String::toUpperCase)
.forEach(System.out::println);
4.2. 终端操作
4.2.1. Stream.forEach()
代码语言:javascript复制memberNames.forEach(System.out::println);
4.2.2. Stream.collect()
代码语言:javascript复制List<String> memNamesInUppercase = memberNames.stream().sorted()
.map(String::toUpperCase)
.collect(Collectors.toList());
System.out.print(memNamesInUppercase);
4.2.3. Stream.match()
所有的matching操作都是终端从挨揍,并且返回boolean 结果
代码语言:javascript复制boolean matchedResult = memberNames.stream()
.anyMatch((s) -> s.startsWith("A"));
System.out.println(matchedResult);
matchedResult = memberNames.stream()
.allMatch((s) -> s.startsWith("A"));
System.out.println(matchedResult);
matchedResult = memberNames.stream()
.noneMatch((s) -> s.startsWith("A"));
System.out.println(matchedResult);
4.2.4. Stream.count()
代码语言:javascript复制long totalMatched = memberNames.stream()
.filter((s) -> s.startsWith("A"))
.count();
4.2.5. Stream.reduce()
reduce()方法根据给出的函数执行流上元素的减少操作,结果是Optional接收这个reduced value。
we are reducing all the strings by concatenating them using a separator #
.
Optional<String> reduced = memberNames.stream()
.reduce((s1,s2) -> s1 "#" s2);
reduced.ifPresent(System.out::println);
输出:
代码语言:javascript复制Amitabh#Shekhar#Aman#Rahul#Shahrukh#Salman#Yana#Lokesh
5. Stream 流中的短路操作
5.1. Stream.anyMatch()
代码语言:javascript复制boolean matched = memberNames.stream()
.anyMatch((s) -> s.startsWith("A"));
5.2. Stream.findFirst()
代码语言:javascript复制String firstMatchedName = memberNames.stream()
.filter((s) -> s.startsWith("L"))
.findFirst()
.get();
6.Java Steam中的并发操作
代码语言:javascript复制List<Integer> list = new ArrayList<Integer>();
for(int i = 1; i< 10; i ){
list.add(i);
}
//Here creating a parallel stream
Stream<Integer> stream = list.parallelStream();
Integer[] evenNumbersArr = stream.filter(i -> i%2 == 0).toArray(Integer[]::new);
System.out.print(evenNumbersArr);
参考网址:
https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html
https://blog.csdn.net/pan_junbiao/article/details/105913518
https://howtodoinjava.com/java8/java-streams-by-examples/
https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html