流是从支持数据处理操作的源生成的元素序列。源可以是数组、文件、集合、函数。流的目的不在于保存数据,而是计算。
通常有5种方式:
1.通过集合生成
List<Integer> integerList = Arrays.asList(1, 2, 3, 4, 5, 6);
Stream<Integer> stream = integerList.stream();
2.通过数组生成
int[] intArr = {1, 2, 3, 4, 5, 6};
IntStream stream = Arrays.stream(intArr); //生成数值流IntStream,可以避免数值计算过程中的拆线装箱
注:Stream API提供了mapToInt、mapToDouble、mapToLong三种方式将对象流【即Stream 】转换成对应的数值流,同时提供了boxed方法将数值流转换为对象流.
3.通过值生成
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6);
4.通过文件生成
Stream<String> lines = Files.lines(Paths.get("data.txt"), Charset.defaultCharset());
5.通过函数生成
iterator方法
Stream<Integer> stream = Stream.iterate(0, n -> n + 2).limit(5);
generator方法
Stream<Double> stream = Stream.generate(Math::random).limit(5);
以上两个方法生成的流均是无限流。
1.中间操作
一个流后面可以跟随多个中间操作,主要目的是为了做数据映射和过滤,返回一个新流交给下一个操作使用。常见的中间操作有filter、map等方法。
2.终端操作
一个流有且只能有一个终端操作,当终端操作执行后,流就被关闭了,因此一个流只能被遍历一次。常见的终端操作有count、collect等方法。
1.filter筛选
List<Integer> integerList = Arrays.asList(1, 2, 3, 4, 5, 6);
Stream<Integer> stream = integerList.stream().filter(i -> i > 3);
2.distinc去重
List<Integer> integerList = Arrays.asList(1, 1, 2, 3, 4, 5);
Stream<Integer> stream = integerList.stream().distinct();
3.limit截断
List<Integer> integerList = Arrays.asList(1, 1, 2, 3, 4, 5);
Stream<Integer> stream = integerList.stream().limit(3);
4.skip跳过
List<Integer> integerList = Arrays.asList(1, 1, 2, 3, 4, 5);
Stream<Integer> stream = integerList.stream().skip(2);
5.map映射
List<String> stringList = Arrays.asList("Java 8", "Lambdas", "In", "Action");
List<Integer> collect = stringList.stream()
.map(String::length)
.collect(Collectors.toList());
6.flatMap流转换
将流中的每个值都转换为另一个流。
List<String> wordList = Arrays.asList("Java 8", "Lambdas", "In", "Action");
List<String> strList = wordList.stream()
.map(w -> w.split(" "))
.flatMap(Arrays::stream)
.distinct()
.collect(Collectors.toList());
7.allMatch匹配所有
List<Integer> integerList = Arrays.asList(1, 2, 3, 4, 5);
if (integerList.stream().allMatch(i -> i > 3)) {
System.out.println("所有元素值都大于3");
} else {
System.out.println("并非所有元素值都大于3");
}
8.anyMatch匹配任意
List<Integer> integerList = Arrays.asList(1, 2, 3, 4, 5);
if (integerList.stream().anyMatch(i -> i > 3)) {
System.out.println("存在值大于3的元素");
} else {
System.out.println("不存在值大于3的元素");
}
9.noneMatch全部不匹配
List<Integer> integerList = Arrays.asList(1, 2, 3, 4, 5);
if (integerList.stream().noneMatch(i -> i > 3)) {
System.out.println("值都小于3的元素");
} else {
System.out.println("值不都小于3的元素");
}
1.count计数
List<Integer> integerList = Arrays.asList(1, 2, 3, 4, 5);
Long result = integerList.stream().count();
2.findFirst查找
List<Integer> integerList = Arrays.asList(1, 2, 3, 4, 5);
Optional<Integer> result = integerList.stream().filter(i -> i > 3).findFirst();
System.out.println(result.orElse(-1));
3.findAny随机查找
List<Integer> integerList = Arrays.asList(1, 2, 3, 4, 5);
Optional<Integer> result = integerList.stream().filter(i -> i > 3).findAny();
System.out.println(result.orElse(-1));
注:findFirst在并行上限制较多,因此并行场景选择findAny方法较为合适。
4.reduce归约
常用场景:
累加
List<Integer> integerList = Arrays.asList(1, 2, 3, 4, 5);
int sum = integerList.stream()
.reduce(0, Integer::sum);
获取最大/小值
List<String> stringList = Arrays.asList("Java 8", "Lambdas", "In", "Action");
Optional<Integer> min = stringList.stream()
.map(String::length)
.reduce(Integer::min);
Optional<Integer> max = stringList.stream()
.map(String::length)
.reduce(Integer::max);
5.foreach遍历
List<String> stringList = Arrays.asList("Java 8", "Lambdas", "In", "Action");
stringList.stream().forEach(System.out::println);
6.collect返回集合
List<String> stringList = Arrays.asList("Java 8", "Lambdas", "In", "Action");
List<Integer> intList = stringList.stream()
.map(String::length)
.collect(toList());
Set<Integer> intSet = stringList.stream()
.map(String::length)
.collect(toSet());
7.joining拼接
List<String> stringList = Arrays.asList("Java 8", "Lambdas", "In", "Action");
String result = stringList.stream()
.map(String::toLowerCase)
.collect(Collectors.joining("-"));
8.groupingBy分组
List<String> stringList = Arrays.asList("Java 8", "Lambdas", "In", "Action");
String result = stringList.stream()
.map(String::toLowerCase)
.collect(Collectors.joining("-"));
9.partioningBy分区
分区是特殊的分组,其分类依据是true和false,因此返回的结果最多可以分为两组。
List<String> stringList = Arrays.asList("Java 12", "Lambdas", "In", "Action");
Map<Boolean, List<String>> collect = stringList.stream().collect(partitioningBy(String::isEmpty));、