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

100
Visualizações
How to sort a list into a custom order forming kind of distinct groups

I have a list of unsorted strings, where entries are one of {A,B,C,D}:

List<String> strings = new ArrayList<>(Arrays.asList("A","C","B","D","D","A","B","C","A","D","B","D","A","C"));

I need to sort / (group) them in a custom order taking one item at time to have a result like:

[A, B, C, D, A, B, C, D, A, B, C, D, A, D]

I am struggling to come up with an idea how to do so. Any help?

I have tried to use a custom Comparator<String> but not able to implement the logic that first A < second A and first D < second A.

Also tried Stream. groupingBy:

Collection<List<String>> coll = strings.stream().collect(Collectors.groupingBy(s -> s)).values();

which groups same strings into groups.

[[A, A, A, A], [B, B, B], [C, C, C], [D, D, D, D]]

But I am not sure how to take one element at a time from above lists till no elements are available. Does anyone have any approach on how to proceed here? Need a hint in the right direction.

over 4 years ago · Santiago Trujillo
3 Respostas
Responde à pergunta

0

Building a whole new list could lead to some other solutions, for example:

Map<String, Long> counts = strings.stream().collect(groupingBy(identity(), TreeMap::new, counting()));
List<String> ordered = new ArrayList<>();
while (!counts.isEmpty()) {
    for (Iterator<Map.Entry<String, Long>> it = counts.entrySet().iterator(); it.hasNext(); ) {
        Map.Entry<String, Long> entry = it.next();
        ordered.add(entry.getKey());
        long newCount = entry.getValue() - 1;
        if (newCount == 0) {
            it.remove();
        } else {
            entry.setValue(newCount);
        }
    }
}

With strings being the input list and ordered the output.

over 4 years ago · Santiago Trujillo Relatório

0

Add a number prefix to each value, sort and remove the prefix, with limitation the array size cannot be far bigger than the number prefix

List<String> strings = new ArrayList<>(Arrays.asList("A","C","B","D","D","A","B","C","A","D","B","D","A","C"));
Map<String, Integer> m = new HashMap<>();
strings.stream()
    .map(i -> String.format("%dx%s", (100000 + m.merge(i, 1, (n, w) -> n+w)), i))
    .sorted()
    .map(i -> i.replaceFirst("^\\d+x", ""))
    .collect(Collectors.toList());
over 4 years ago · Santiago Trujillo Relatório

0

This is roughly the same logic as sp00m's answer, but implemented with two streams:

Map<String, Long> groups = strings.stream()
    .collect(Collectors.groupingBy(Function.identity(), 
            TreeMap::new, 
            Collectors.counting()));

List<String> result = IntStream.range(0, groups.values().stream()
                          .mapToInt(Long::intValue).max().orElseThrow())
    .mapToObj(c -> groups.keySet().stream().filter(k -> groups.get(k) > c))
    .flatMap(Function.identity())
    .collect(Collectors.toList());

The sorting is taken care of by TreeMap. Just be sure that your actual list elements are comparable (or that you give the right TreeMap supplier)

over 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