Reputation: 1551
I want this stream to throw an exception if there are more than 1 results that survive the filter. Is there any way to achieve this?
One idea is to use .count()
, but I'll have to create the stream again.
Optional<Result> filteredresultSet = results.stream()
.filter(c -> c.equals("TOMATO))
.findAny();
Upvotes: 1
Views: 255
Reputation: 4555
You can replace findAny()
by reduce()
and throw an exception in the accumulator:
Optional<String> filteredresultSet = results.stream()
.filter("TOMATO"::equals)
.reduce((s1, s2) -> {
throw new MyException();
});
An alternative to find out exactly how many elements are left and still retrieve the first one is to use a small array or custom object to store the count and first element:
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);
This would return you an instance of Container
, or null
if the stream is empty. You can then check the count
and return an Optional
of the value
.
Upvotes: 3
Reputation: 28163
A simple way is to use .limit(2)
on the stream to short-circuit after two matches and then collect to a list or array.
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));
Upvotes: 1