The first step is to use Stream#allMatch(Predicate)
to check the tuple for either the combination of [foo, bar]
or [bar, baz]
and the size of the tuple.
In the second step I have converted the inner array into a Set<String>
which makes it easy to resolve cases like [foo, foo]
as the duplicates would be removed and also we can use Set.contains()
for a O(1) lookup to check either [foo, bar]
or [bar, baz]
is present in the stream of tuples:
class TupleTest {
@org.junit.jupiter.api.Test
void testTupleOfCandidates_True() {
Stream<String[]> candidates = Stream.of(new String[]{"bar", "foo"}, new String[]{"bar", "baz"});
assertTrue(isCandidateStreamValid(candidates));
candidates = Stream.of(new String[]{"bar", "foo"}, new String[]{"bar", "baz"});
assertTrue(isCandidateStreamValid(candidates));
}
@org.junit.jupiter.api.Test
void testTupleOfCandidates_False() {
Stream<String[]> candidates = Stream.of(new String[]{"foo", "foo"}, new String[]{"bar", "baz"});
assertFalse(isCandidateStreamValid(candidates));
candidates = Stream.of(new String[]{"bar", "foo"}, new String[]{"bar", "baz"}, new String[]{"baz", "bar"});
assertTrue(isCandidateStreamValid(candidates));
}
public boolean isCandidateStreamValid(Stream<String[]> candidates){
return candidates.allMatch(arr -> {
Set<String> data = new HashSet(Arrays.asList(arr));
return data.size() == 2
&&
((data.contains("foo") && data.contains("bar"))
||
(data.contains("bar") && data.contains("baz")));
});
}
}