stream流添加终端操作

stream流添加终端操作

避免使用reduce()归约操作

使用reduce()并不是最简单的归约方法。

You need to make sure that the binary operator you provide is associative, then you need to know if it has an identity element.

计算stream流中的元素个数

示例

Collection<String> strings =
        List.of("one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten");

long count =
        strings.stream()
                .filter(s -> s.length() == 3)
                .count();
System.out.println("count = " + count);

结果

count = 4

依次消费stream流中的元素

foreach()

示例1

Stream<String> strings = Stream.of("one", "two", "three", "four");
strings.filter(s -> s.length() == 3)
       .map(String::toUpperCase)
       .forEach(System.out::println);

结果

ONE
TWO

示例2

Stream<String> strings = Stream.of("one", "two", "three", "four");
List<String> result = new ArrayList<>();

strings.filter(s -> s.length() == 3)
       .map(String::toUpperCase)
       .forEach(result::add);

System.out.println("result = " + result);

结果

result = [ONE, TWO]

示例2的改写

Stream<String> strings = Stream.of("one", "two", "three", "four");

List<String> result = 
    strings.filter(s -> s.length() == 3)
           .map(String::toUpperCase)
           .collect(Collectors.toList());

jdk16可以改写成

Stream<String> strings = Stream.of("one", "two", "three", "four");

List<String> result = 
    strings.filter(s -> s.length() == 3)
           .map(String::toUpperCase)
           .toList();

注意返回的result是不可变的。

在集合或数组中收集stream流元素

Stream API提供了几种收集stream流中被处理的数据到集合中。

在你选择你所需的模式前你需要考虑以下的问题:

  • 你是否需要构建一个不变的List

  • 你是需要ArrayList还是LinkedList

  • 你是否确切的知道所处理的stream流的具体元素个数

  • 你是否需要收集到第三方或者自己定义的List

收集到ArrayList

示例

Stream<String> strings = Stream.of("one", "two", "three", "four");

List<String> result = 
    strings.filter(s -> s.length() == 3)
           .map(String::toUpperCase)
           .collect(Collectors.toList());

这是最简单的方法,但请注意当stream流中元素很多,会造成ArrayList拷贝到更大ArrayList并伴随着gc收集之前ArrayList

可以使用Collectors.toCollection()指定更大容量大ArrayList避免多次gc

Stream<String> strings = ...;

List<String> result = 
    strings.filter(s -> s.length() == 3)
           .map(String::toUpperCase)
           .collect(Collectors.toCollection(() -> new ArrayList<>(10_000)));

收集到不变的List

示例

Stream<String> strings = ...;

List<String> result = 
    strings.filter(s -> s.length() == 3)
           .map(String::toUpperCase)
           .collect(Collectors.toUnmodifiableList()));

jdk16

Stream<String> strings = ...;

List<String> result = 
    strings.filter(s -> s.length() == 3)
           .map(String::toUpperCase)
           .toList();

收集到自制的List

使用Collectors.toCollection()

Stream<String> strings = ...;

List<String> result = 
    strings.filter(s -> s.length() == 3)
           .map(String::toUpperCase)
           .collect(Collectors.toCollection(LinkedList::new));

收集到Set

可以使用Collectors.toCollection(HashSet::new)或者更简洁的Collectors.toSet(),注意这俩者还是有细微的差别,后面介绍。

Stream<String> strings = ...;

Set<String> result = 
    strings.filter(s -> s.length() == 3)
           .map(String::toUpperCase)
           .collect(Collectors.toSet());

如果你需要收集到不变的Set

Stream<String> strings = ...;

Set<String> result = 
    strings.filter(s -> s.length() == 3)
           .map(String::toUpperCase)
           .collect(Collectors.toUnmodifiableSet());

收集到数组

示例

Stream<String> strings = ...;

String[] result = 
    strings.filter(s -> s.length() == 3)
           .map(String::toUpperCase)
           .toArray(String[]::new);

System.out.println("result = " + Arrays.toString(result));

结果

result = [ONE, TWO]

提取stream流中最大和最小元素

示例

Stream<String> strings = Stream.of("one", "two", "three", "four");
String longest =
     strings.max(Comparator.comparing(String::length))
            .orElseThrow();
System.out.println("longest = " + longest);

结果

longest = three

stream流中查找元素

findFirst(), findAny()

Collection<String> strings =
        List.of("one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten");

String first =
    strings.stream()
           // .unordered()
           // .parallel()
           .filter(s -> s.length() == 3)
           .findFirst()
           .orElseThrow();

System.out.println("first = " + first);

结果

first = one

检查stream流中的元素是否与给定的Predicate匹配

  • anyMatch(predicate)只要stream流中有一个元素匹配就返回true

  • allMatch(predicate)stream流中所有元素都匹配才返回true

  • noneMatch(predicate)stream流中没有一个元素匹配才返回true

Collection<String> strings =
    List.of("one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten");

boolean noBlank  = 
        strings.stream()
               .allMatch(Predicate.not(String::isBlank));
boolean oneGT3   = 
        strings.stream()
               .anyMatch(s -> s.length() == 3);
boolean allLT10  = 
        strings.stream()
               .noneMatch(s -> s.length() > 10);
        
System.out.println("noBlank = " + noBlank);
System.out.println("oneGT3  = " + oneGT3);
System.out.println("allLT10 = " + allLT10);

结果

noBlank = true
oneGT3  = true
allLT10 = true

stream流的短路处理

stream流的终端处理分类:一些需要处理完所有的元素才返回,例如count(), max(), min(), average(), forEach(), toList(), toArray()等。一些不需要处理完所有数据即可返回,例如findFirst(), findAny(), anyMatch(), allMatch(), noneMatch()

短路处理:无需处理stream流的所有元素即可产生结果。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值