I want to check, if a LongStream
contains a specific number at least once, but not totally consists of this number:
My approach:
public static boolean containsNum(LongStream input, int n) {
return input.anyMatch(i -> i == n);
}
Tests:
assertEquals(false, containsNum(LongStream.of(1, 2, 3), 19)); // ok
assertEquals(true, containsNum(LongStream.of(1, 2, 3, 19), 19)); //ok
assertEquals(true, containsNum(LongStream.of(1, 19, 19), 19)); //ok
assertEquals(false, containsNum(LongStream.of(1), 19)); //ok
assertEquals(false, containsNum(LongStream.of(19, 19), 19)); // FAIL
assertEquals(false, containsNum(LongStream.of(19), 19)); //FAIL
I know that anyMatch
can´t work in my problem, but the best solution I found. How can I get all tests passing?
It sounds like a reduce function, as Andy's answer shows, but that would go through the whole stream instead of stopping as soon as you found the number and a different number.
The problem is that those ...Match
methods of streams only look at one element at a time, i.e. you would have to save knowledge about the passed elements in some outside state variable. wero and Roland demonstrate this in their answers.
One possibility without relying on outside state while only checking as many elements as necessary would be:
boolean pass = longStream.map(l -> l == number ? 1 : 0)
.distinct()
.limit(2)
.count()
== 2;
You can reduce the stream, keeping a pair of booleans:
Let's say you've got some Pair
class; then:
Stream<Pair> pairs =
input.map(i -> (i == n) ? Pair.of(true, false) : Pair.of(false, true));
Then, reduce this stream by or-ing together the two elements:
Pair reduces =
pairs.reduce(
Pair.of(false, false),
(a, b) -> Pair.of(a.first || b.first, a.second || b.second));
Then check (and return) that both elements are true:
return reduced.first && reduced.second;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With