How to know if the list contains both elements that meet and that do not meet a condition, using stream?

5

I have a list of columns, I need to know if this list contains both columns that are keys as columns that are not keys.

  

I guarantee the existence of at least one column in the list

My column class:

public class Coluna {
  public boolean chave;
  public boolean isChave() { return chave; }
}

My verification is now:

List<Coluna> minhasColunas = ...;
Predicate<Coluna> ehChave = Coluna::isChave;
boolean possuiColunasMistas =
    minhasColunas.stream().anyMatch(ehChave) &&
    minhasColunas.stream().anyMatch(ehChave.negate());

Is there any more idiomatic way of doing this check? I found it very strange to go through two streams to get the result.

On a more imperative check, I would do the following:

List<Coluna> minhasColunas = ...;
boolean achouChave = false;
boolean achouNaoChave = false;
for (Coluna c: minhasColunas) {
  if (c.chave) {
    achouChave = true;
    if (achouNaoChave) {
      break;
    }
  } else {
    achouNaoChave = true;
    if (achouChave) {
      break;
    }
  }
}

boolean possuiColunasMistas = achouChave && achouNaoChave;

After creating the question, and chatting with @Anderson Carlos Woss , I ended up creating some test scenarios for that question. They are available here: link

So if you want to validate your own answer, implement the boolean possuiColunasMistas(List<Coluna> colunas) method and then just run the test cases with JUnit.

    
asked by anonymous 14.06.2018 / 15:41

1 answer

2

A slightly simpler logic would be to get the value of the first element from the list and just check if there is any other element in it. If the list is homogeneous, all values will be equal and therefore will not find a different value.

I think it would be close to:

boolean primeiraChave = lista.get(0).isChave();
boolean possuiColunasMistas = lista.stream().skip(1).anyMatch(it -> it.isChave() != primeiraChave)

So possuiColunasMistas will true only for heterogeneous lists.

  

Note: Using skip(1) is optional, since comparing the first element with itself will not change the result; but it also does not make sense to check if it is different from itself.

    
14.06.2018 / 15:55