如果有1个以上的结果可以通过过滤器,我希望此流引发异常。有什么办法可以做到这一点?
一个想法是使用.count()
,但我将不得不再次创建流。
Optional<Result> filteredresultSet = results.stream()
.filter(c -> c.equals("TOMATO))
.findAny();
答案 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));