Note that by looking at your three rules together, you don’t need to do individual checks:
A list can only contain all-true or all-false, but if either is valid, the combined rule is “all (boolean) values must be the same” which can be tested in a single expression like !booleanList.contains(!booleanList.get(0))
. But there’s the third alternative:
if a row contains mixed values, then only the first element can be true, otherwise the validation must fail.
This basically says: if there is a false
value, all but the first element must be false as well. This rule makes the other two obsolete:
- if there is no
false
value, then all values are true
- if there is a
false
value, the first element might be true, so all values being false
is a special case of this rule
- in other words, if there is a
false
value, the value of the first element is irrelevant
Therefore, we can short-cut the test by looking at any other element than the first one, e.g. at index 1
and selecting one rule to test, based on that value:
- if the value is
true
, all values are required to be true
- if the value is
false
, all but the first values are required to be false
- as a corner case, if the list is smaller than two elements, there is no contradicting element, so the list is valid
So the entire condition can be expressed as
list.size()<2 ||
list.get(1)? // has a TRUE at a position other than the first
!list.contains(false): // all are TRUE
!list.subList(1, list.size()).contains(true); // all except the first are FALSE
Regarding the Stream API,
!list.contains(x)
can be expressed as list.stream().noneMatch(Predicate.isEqual(x))
and
!list.subList(1, list.size()).contains(x)
can be expressed as list.stream().skip(1).noneMatch(Predicate.isEqual(x))
,
but there’s no reason to use the Stream API here.
However, for validating a List
of List
s, you can use the Stream API to check whether all sublists fulfill the condition:
static boolean validate(List<List<Boolean>> list2D) {
return list2D.stream().allMatch(list-> list.size()<2 ||
list.get(1)? !list.contains(false): !list.subList(1, list.size()).contains(true)
);
}