Java Lambda表达式用于计数唯一对象

时间:2019-02-02 20:41:09

标签: java lambda java-8

我在下面设置了此流,并且无法在.map上使用方法count()。仅在过滤器上。但是我还没有设置任何过滤条件。我该如何在下面的此流的字符串数组上做到这一点?

我想用replaceAll中的正则表达式对字符串进行排序,并获得唯一的字符串,并获得唯一字符串的总数。

Stream newStream = Arrays.stream(arr)
                    .map(s -> s.replaceAll("[^a-z]", ""))
                    .distinct()

3 个答案:

答案 0 :(得分:3)

如果您要计算distinct字符串的数量,可以像这样:

long countDistinct = Arrays.stream(arr)
        .map(s -> s.replaceAll("[^a-z]", ""))
        .distinct() // intermediate operation with unique strings as 'Stream' return type
        .count();   // terminal operation with count of such strings as return type

答案 1 :(得分:1)

我不确定我是否完全理解您的要求。似乎您想要一个List,并且在将正则表达式应用于数组的每个元素之后对不同的字符串进行排序。 List将同时具有元素和数量:

List<String> list = Arrays.stream(arr)
    .map(s -> s.replaceAll("[^a-z]", ""))
    .distinct()
    .sorted()
    .collect(Collectors.toList());

现在,list保存了元素。而且,如果您还想知道其中包含多少个元素,只需使用List.size方法:

int count = list.size();

编辑:如果您还需要一个Stream且字符串已更改,唯一且已排序,只需从Stream创建一个新的list

Stream<String> newStream = list.stream();

答案 2 :(得分:0)

作为列表进行收集和获取总数都是终端操作,因此,您只能在实时流上执行

如果必须使用 相同 流来同时获得字符串和计数列表,则可以使用一个(hacky)选项Supplier<Stream<T>>

String text = "FOO bar BAZ TEXT text some";
String[] arr = text.split(" ");

Supplier<Stream<String>> sameStream = () -> Arrays.stream(arr)
        .map(s -> s.replaceAll("[^a-z]", ""))
        .distinct()
        .filter(s -> !s.isEmpty())
        .sorted();

System.out.println("Unique strings are: " + sameStream.get().collect(Collectors.toList()));
System.out.println("Count of Unique strings are: " + sameStream.get().count());

上面产生此输出:

Unique strings are: [bar, some, text]
Count of Unique strings are: 3