stream流

什么是stream流呢

Stream is a sequence of objects that supports various methods which can be pipelined to produce the desired result. Following are the characteristics of a Stream −

  • Stream is not a data structure instead it takes input from the Collections, Arrays, or I/O channels.
  • Stream doesn’t change the original data structure, for example, filter method takes elements from a stream and puts them into a new stream.
  • Stream operations are either lazy or eager.
  • Stream is functional in nature, for example, filter, map, limit, reduce, find, match, and so on.
  • Stream doesn’t modify its source. For example, filtering a Stream obtained from a collection produces a new Stream without the filtered elements, rather than removing elements from the source collection.

1.1 什么是stream流

stream流是一个对象序列,它支持各种方法,这些方法可以被管道化以产生所需的结果。以下是流的特征

  • Stream不是数据结构,而是从集合,数组或I / O通道中获取输入。
  • Stream不会更改原始数据结构,例如,过滤器方法从流中获取元素,并将它们放入新的流中。
  • 流操作是惰性的或者急切的。
  • Stream是函数式的,例如,过滤器,映射,限制,减少,查找,匹配等。
  • Stream不会修改其源。例如,从集合获取的流过滤后,产生一个新的流而不是从源集合中删除过滤的元素。

1.2 stream流的特点

  • 1.不是数据结构,而是对数据的计算
  • 2.不会存储数据,不会改变源对象,相反,他们会返回一个持有结果的新Stream
  • 3.懒执行,只有在需要结果的时候才执行

1.3 stream流的创建

1.3.1 通过集合创建

1
2
List<String> list = Arrays.asList("a","b","c");
Stream<String> stream

1.3.2 通过数组创建

1
2
String[] strArray = new String[] {"a","b","c"};
Stream<String> stream = Arrays.stream(strArray);

1.3.3 通过Stream的of创建

1
Stream<String> stream = Stream.of("a","b","c");

1.3.4 创建无限流

1
2
3
4
5
6
7
8
//迭代
Stream<Integer> stream = Stream.iterate(0, (x) -> x + 2);
stream.forEach(System.out::println);

//生成
Stream.generate(() -> Math.random())
.limit(5)
.forEach(System.out::println);

1.4 stream流的操作

1.4.1 中间操作

中间操作不会执行任何操作,它只是返回一个新的流,这样我们就可以将多个操作依次链接在一起,形成一个流水线,除非流水线上触发终端操作,否则中间操作不会执行任何处理!

  • 1.筛选与切片

filter——接受Lambda,从流中排除某些元素

limit——截断流,使其元素不超过给定数量

skip(n)——跳过元素,返回一个扔掉了前n个元素的流。若流中元素不足n个,则返回一个空流。与limit(n)互补

distinct——筛选,通过流所生成元素的hashCode()和equals()去除重复元素

  • 2.映射

map——接收Lambda,将元素转换成其他形式或提取信息。接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。

flatMap——接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流

  • 3.排序

sorted()——自然排序

sorted(Comparator com)——定制排序

flatMap的使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//flatMap(Function f)
//Function的输入是一个流,输出是一个流
//flatMap(Function f)
//Function的输入是一个流,输出是一个流

//将每个单词转成大写,然后转成流
Stream<String> stream = list.stream()
.map(String::toUpperCase);

//将每个单词转成大写,然后转成流
Stream<String> stream = list.stream()
.flatMap(StreamAPITest1::filterCharacter);

public static Stream<Character> filterCharacter(String str) {
List<Character> list = new ArrayList<>();
for (Character ch : str.toCharArray()) {
list.add(ch);
}
return list.stream();
}

1.4.2 终止操作

终止操作会从流的流水线生成结果。其结果可以是任何不是流的值,例如:List、Integer、Void等。

  • 1.匹配与查找

allMatch——检查是否匹配所有元素

anyMatch——检查是否至少匹配一个元素

noneMatch——检查是否没有匹配的元素

findFirst——返回第一个元素

findAny——返回当前流中的任意元素

count——返回流中元素的总个数

max——返回流中最大值

min——返回流中最小值

  • 2.规约

reduce(T identity, BinaryOperator) / reduce(BinaryOperator)——可以将流中元素反复结合起来,得到一个值。返回T

1
2
3
4
//计算1-10的自然数的和
Integer sum = list.stream()
.reduce(0, Integer::sum);
System.out.println(sum);
  • 3.收集

collect——将流转换为其他形式。接收一个Collector接口的实现,用于给Stream中元素做汇总的方法

1
2
3
4
//收集
List<String> list = stream.collect(Collectors.toList());
Set<String> set = stream.collect(Collectors.toSet());
HashSet<String> hs = stream.collect(Collectors.toCollection(HashSet::new));
  • 4.归约

reduce()——可以将流中元素反复结合起来

1.4.3