Java 获取元素数量

Java 获取元素数量,用户希望获取流中元素的数量。使用 java.util.stream.Stream 接口定义的 count 方法,或 java.util.stream.Collectors 类定义的 counting 方法。本范例相当简单,目的是为范例下游收集器讨论的下游收集器作铺垫。

Java 获取元素数量 问题描述

用户希望获取流中元素的数量。

Java 获取元素数量 解决方案

使用 java.util.stream.Stream 接口定义的 count 方法,或 java.util.stream.Collectors 类定义的 counting 方法。

Java 获取元素数量 具体实例

本范例相当简单,目的是为范例下游收集器讨论的下游收集器作铺垫。
如例 3-39 所示,Stream 接口定义了 count 默认方法,它能返回 long 型数据。

例 3-39 利用 Stream.count 方法获取元素数量

long count = Stream.of(3, 1, 4, 1, 5, 9, 2, 6, 5).count();
System.out.printf("There are %d elements in the stream%n", count); ➊

➊ 打印 There are 9 elements in the stream
count 方法的有趣之处在于它的实现方式。根据 Javadoc 的描述,“这是一种特殊的归约操作,相当于”:

return mapToLong(e -> 1L).sum();

首先,流的每个元素都被映射为 1(long)。然后,mapToLong 方法生成 LongStream,它定义了 sum 方法。换言之,先将所有元素映射为 1,再将它们相加,简单明了。
此外,Collectors 类定义了一种类似的方法 counting,如例 3-40 所示。

例 3-40 利用 Collectors.counting 方法获取元素数量

count = Stream.of(3, 1, 4, 1, 5, 9, 2, 6, 5)
    .collect(Collectors.counting());
System.out.printf("There are %d elements in the stream%n", count);

这两种方法得到的结果并无不同,但既然已有 Stream.count,为什么还要讨论 Collectors.counting 呢?
我们当然可以使用 Stream.count 方法,按说也应该这样处理。不过“下游收集器”(downstream collector)的使用将在范例下游收集器进行详细讨论。就目前而言,我们考虑例 3-41。

例 3-41 对根据长度划分的字符串计数

Map<Boolean, Long> numberLengthMap = strings.stream()
    .collect(Collectors.partitioningBy(
        s -> s.length() % 2 == 0, ➊
        Collectors.counting()));  ➋

numberLengthMap.forEach((k,v) -> System.out.printf("%5s: %d%n", k, v));
//
// false: 4
//  true: 8

❶ 谓词
❷ 下游收集器
partitioningBy 方法的第一个参数是 Predicate,其作用是将字符串分为满足谓词和不满足谓词的两类。如果 partitioningBy 方法只有这一个参数,则结果为 Map<Boolean, List<String>>,其中键为 truefalse,值为偶数长度和奇数长度字符串的列表。
本例采用 partitioningBy 方法的双参数重载形式,它传入 PredicateCollectorCollector 被称为下游收集器,用于对返回的每个字符串列表进行后期处理。这就是 Collectors.counting 方法的用例。双参数形式的 partitioningBy 方法将输出 Map<Boolean, Long>,其值为流中偶数长度和奇数长度字符串的数量。
Stream 接口定义的其他几种方法在 Collectors 类中也有对应的方法,其他章节将对它们进行讨论。简而言之,直接处理流时请使用 Stream 定义的方法,而 Collectors 定义的方法适用于 partitioningBygroupingBy 操作的下游后期处理。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程