记录已过滤流的大小

时间:2018-08-06 22:48:13

标签: java java-stream

如果有1个以上的结果可以通过过滤器,我希望此流引发异常。有什么办法可以做到这一点?

一个想法是使用.count(),但我将不得不再次创建流。

Optional<Result> filteredresultSet = results.stream()
        .filter(c -> c.equals("TOMATO))
        .findAny();

2 个答案:

答案 0 :(得分:3)

您可以将findAny()替换为reduce()并在累加器中引发异常:

Optional<String> filteredresultSet = results.stream()
                                            .filter("TOMATO"::equals)
                                            .reduce((s1, s2) -> {
                                                throw new MyException();
                                            });

确切找出还剩下多少个元素并仍检索第一个元素的另一种方法是使用小型数组或自定义对象存储计数和第一个元素:

results.stream().filter("TOMATO"::equals).collect(Container::new, (c, e) -> {
    c.count++;
    if (c.value == null)
    {
        c.value = e;
    }
}, (c1, c2) -> c1.count += c2.count);

这将返回Container的实例,如果流为空,则返回null的实例。然后,您可以检查count并返回Optional中的value

答案 1 :(得分:1)

一种简单的方法是在两次匹配后在流上使用.limit(2)使其短路,然后收集到列表或数组中。

List<Result> filtered = results.stream()
    .filter(c -> c.equals("TOMATO"))
    .limit(2)   // we don't need to know if there are more than 2 matches
    .collect(toList());

if (filtered.size() > 1) {
    // throw or log
}

return filtered.isEmpty() ? Optional.empty() : Optional.of(filtered.get(0));