Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

284
Visualizações
LinkedHashMap entrySet's order not being preserved in a stream (Android)

I'm creating a very simple form validation utility for a sign up screen, and I'm running into some unexpected behavior concerning LinkedHashMap and a stream created from its entrySet.

I'm storing validation results in a LinkedHashMap, with the following ordering of statements:

Map<ValidationResult.SignUpField, Boolean> fieldStatuses = new LinkedHashMap<>();

fieldStatuses.put(EMAIL, isValidEmail(emailAddress));
fieldStatuses.put(USERNAME, isValidUsername(username));
fieldStatuses.put(BIRTHDAY, isValidBirthday(birthday));
fieldStatuses.put(PASSWORD, isValidPassword(password));
fieldStatuses.put(CONFIRM_PASSWORD, password.equals(confirmedPassword));

List<ValidationEntry> invalidFields = aggregateInvalidFields(fieldStatuses);

One particular iteration yields all of the above fields invalid except for "confirm password". Using a simple for loop over the entry set and omitting valid results, the invalid results appear in the following order:

  • Email
  • Username
  • Birthday
  • Password

I then attempted to make use of the subset of Stream API's available on Android (targeting version 25 with a min of 19, hence the lack of Collectors.toMap()):

private static List<ValidationEntry> aggregateInvalidFields(Map<ValidationResult.SignUpField, Boolean> fields) {
    List<ValidationEntry> invalidFields = new ArrayList<>();
    fields.entrySet()
            .stream()
            .filter(entry -> !entry.getValue())
            .forEachOrdered(entry -> {
                ValidationResult.SignUpField field = entry.getKey();
                invalidFields.add(new ValidationEntry(field, lookUpErrorCode(field)));
            });
    return invalidFields;
}

But that code yields the following order:

  • Birthday
  • Password
  • Username
  • Email

What exactly is happening here, why is the result of the stream not honoring the insertion order of the LinkedHashMap? Note that if I swap out forEachOrdered with forEach, it's still not insertion ordered.

about 4 years ago · Santiago Trujillo
1 Respostas
Responde à pergunta

0

This behavior is a known bug in Android's 7.0 / 7.1 implementation of LinkedHashMap.

The LinkedHashMap's collection views' spliterators for entrySet, values and keySet correctly report that they are ORDERED but actually they aren't because the spliterator implementation of the parent class (HashMap) is used internally.

This behavior has already been documented in the Javadoc and workarounds are also proposed there.

The fix has been commited on 2016-08-16 and will appear in the next Android release.

For clarification: Google became aware of this bug at first in 2017-01, so the "fix" mentioned above was an accidental fix. If they had known about this problem earlier, the resolution would have been included in 7.1

about 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda