Como imprimir o conteúdo de um HashMap em ordem ascendente com base nos seus valores?

tenho isto HashMap que preciso imprimir em ordem ascendente de acordo com o valores contida nele (as chaves não.).

Mas a ordem quando a imprimo é aparentemente aleatória.

Qual é a melhor maneira de imprimir ordem de valores ascendente?

Map<String, String> codes = new HashMap<String, String>();

codes.put("A1", "Aania");
codes.put("X1", "Abatha");
codes.put("C1", "Acathan");
codes.put("S1", "Adreenas");

por outras palavras, o exemplo acima deve ser impresso como este:

A1, Aania
X1, Abatha
C1, Acathan
S1, Adreenas
Author: Carlsberg, 2010-08-31

13 answers

Você não vai ser capaz de fazer isso a partir da classe HashMap sozinho.

Eu levaria o Map<String, String> codes, construiria um mapa inverso de TreeMap<String, String> reversedMap onde você mapeia os valores do mapa de codes para as teclas (isto exigiria que o seu mapa original tivesse um mapeamento de chave a valor). Dado que o 'TreeMap' oferece iteradores que devolvem os itens por ordem crescente, isto dar-lhe-á a combinação valor/chave do primeiro mapa na ordem (ordenada pelos valores) que você desejar.

Map<String, String> reversedMap = new TreeMap<String, String>(codes);

//then you just access the reversedMap however you like...
for (Map.Entry entry : reversedMap.entrySet()) {
    System.out.println(entry.getKey() + ", " + entry.getValue());
}

Existem várias bibliotecas de Coleções (coleções comuns, coleções Google, etc) que têm implementações bidirecionais semelhantes.

 36
Author: matt b, 2016-10-12 12:50:06

Você vai precisar fazer uma lista das chaves, ordená-las de acordo com os valores correspondentes, em seguida, iterar sobre as chaves ordenadas.

Map<String, String> map = getMyMap();
List<String> keys = new ArrayList<String>(map.keySet());
Collections.sort(keys, someComparator);
for (String key: keys) {
    System.out.println(key + ": " + map.get(key));
}

Quanto ao que usar para someComparator, Aqui estão algumas rotinas úteis e genéricas de criação de comparadores que muitas vezes acho úteis. O primeiro ordena pelos valores de acordo com a sua ordenação natural, e o segundo permite-lhe especificar qualquer comparador arbitrário para ordenar os valores:

public static <K, V extends Comparable<? super V>>
        Comparator<K> mapValueComparator(final Map<K, V> map) {
    return new Comparator<K>() {
        public int compare(K key1, K key2) {
            return map.get(key1).compareTo(map.get(key2));
        }
    };
}

public static <K, V>
        Comparator<K> mapValueComparator(final Map<K, V> map,
                                         final Comparator<V> comparator) {
    return new Comparator<K>() {
        public int compare(K key1, K key2) {
            return comparator.compare(map.get(key1), map.get(key2));
        }
    };
}
 11
Author: Sean, 2010-08-31 01:05:26
Está na hora de adicionar lambdas.
codes.entrySet()
    .stream()
    .sorted(Comparator.comparing(Map.Entry::getValue))
    .forEach(System.out::println);
 6
Author: Vladimir S., 2015-04-27 08:22:47

O laço for de for (Mapa.Entrada: codes.entrySet() não funcionou para mim. Usou Iterator em vez disso.

Iterator<Map.Entry<String, String>> i = codes.entrySet().iterator(); 
while(i.hasNext()){
    String key = i.next().getKey();
    System.out.println(key+", "+codes.get(key));
}
 5
Author: psun, 2012-11-20 07:04:22

Só precisas de usar:

 Map<>.toString().replace("]","\n");

E substitui o parêntesis quadrado final de cada tecla=valor definido com uma nova linha.

 4
Author: ole scharling, 2016-04-21 08:52:11
  1. Criar um TreeMap<String,String>
  2. Adicione cada um dos itens HashMap com o valor como chave.
  3. iterate the TreeMap

Se os valores não são unicos, você precisaria de uma lista na segunda posição.

 2
Author: bmargulies, 2010-08-31 11:26:34

Java 8

map.entrySet().stream().sorted(Map.Entry.comparingByValue()).forEach(System.out::println);
 2
Author: bluehallu, 2017-04-24 15:29:19

Você pode usar uma lista do conjunto de itens em vez do conjunto de chaves e é uma escolha mais natural dado que você está ordenando com base no valor. Isto evita muitas pesquisas desnecessárias na ordenação e impressão das entradas.

Map<String, String> map = ...
List<Map.Entry<String, String>> listOfEntries = new ArrayList<Map.Entry<String, String>>(map.entrySet());
Collections.sort(listOfEntries, new SortByValueComparator());
for(Map.Entry<String, String> entry: listOfEntries)
   System.out.println(entry);

static class SortByValueComparator implements Comparator<Map.Entry<String, String>> {
   public int compareTo(Map.Entry<String, String> e1, Map.Entry<String, String> e2) {
       return e1.getValue().compateTo(e2.getValue());
   }
}
 1
Author: Peter Lawrey, 2015-07-02 01:42:15
Acho que o código mais simples e mais curto é este.: public void listPrinter(LinkedHashMap caseList) {
    for(Entry entry:caseList.entrySet()) {
        System.out.println("K: \t"+entry.getKey()+", V: \t"+entry.getValue());
    }
}
 0
Author: TheTeslaa, 2017-06-06 09:45:20

A solução mais simples seria usar um mapa ordenado como o TreeMap em vez de HashMap. Se você não tem controle sobre a construção do mapa, então a solução mínima seria construir um conjunto ordenado de chaves. Não precisas de um mapa novo.

Set<String> sortedKeys = new TreeSet<String>();
sortedKeys.addAll(codes.keySet());

for(String key: sortedKeys){
    println(key  + ":" + codes.get(key));
}
 -1
Author: aar, 2010-08-31 19:00:12

Tenta:

try
{
    int cnt= m.getSmartPhoneCount("HTC",true);      
    System.out.println("total count of HTC="+cnt);
}  
catch (NoSuchBrandSmartPhoneAvailableException e)
{
    // TODO Auto-generated catch 
    e.printStackTrace();
}
 -2
Author: deeps, 2015-04-27 09:28:47
 SmartPhone[] sp=new SmartPhone[4];
 sp[0]=new SmartPhone(1,"HTC","desire","black",20000,10,true,true);
 sp[1]=new SmartPhone(2,"samsung","grand","black",5000,10,false,true);
 sp[2]=new SmartPhone(14,"google nexus","desire","black",2000,30,true,false);
 sp[3]=new SmartPhone(13,"HTC","desire","white",50000,40,false,false);
 -3
Author: deeps, 2015-04-27 08:20:12
while (itr.hasNext()) {
    Vehicle vc=(Vehicle) itr.next();
    if(vc.getVehicleType().equalsIgnoreCase(s)) {
        count++;
    }
}
 -3
Author: Roks, 2015-04-27 09:38:37