ccpizza ccpizza - 2 years ago 113
Java Question

Java: how to check for boolean conditions in two-dimensional lists/arrays?

Given a table-like data structure, e.g. an arraylist of arraylists (a 2D array, or some other iterable data structure), what would be the cleanest way to check the elements against specific rules?

For example given the following data:

[true, false, false, true]
[false, false, false, false]
[true, false, false, false]

How can I enforce that either of the three conditions are satisfied:

  • all elements in all rows are

  • all elements in all rows are

  • if a row contains mixed values, then only the first element can be
    , otherwise the validation must fail.

For example, the data above must not pass validation because of a
value in position [0, 3].

Apparently one way to avoid looping in Java 8 is using;
; — this would cover the first two conditions, not very clear yet about the third condition.

Answer Source

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 and
  • !list.subList(1, list.size()).contains(x) can be expressed as,

but there’s no reason to use the Stream API here.

However, for validating a List of Lists, you can use the Stream API to check whether all sublists fulfill the condition:

static boolean validate(List<List<Boolean>> list2D) {
    return> list.size()<2 ||
        list.get(1)? !list.contains(false): !list.subList(1, list.size()).contains(true)
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download