Classificando HashMap por valores

Eu preciso classificar meu HashMap acordo com os valores armazenados nele. O HashMap contém o nome dos contatos armazenados no telefone.

Também preciso que as chaves sejam classificadas automaticamente assim que eu classificar os valores, ou você pode dizer que as chaves e valores estão vinculados, portanto, quaisquer alterações nos valores devem ser refletidas nas chaves.

 HashMap map = new HashMap(); map.put(1,"froyo"); map.put(2,"abby"); map.put(3,"denver"); map.put(4,"frost"); map.put(5,"daisy"); 

Saída exigida:

 2,abby; 5,daisy; 3,denver; 4,frost; 1,froyo; 

Assumindo Java, você poderia classificar o hashmap assim:

 public LinkedHashMap sortHashMapByValues( HashMap passedMap) { List mapKeys = new ArrayList<>(passedMap.keySet()); List mapValues = new ArrayList<>(passedMap.values()); Collections.sort(mapValues); Collections.sort(mapKeys); LinkedHashMap sortedMap = new LinkedHashMap<>(); Iterator valueIt = mapValues.iterator(); while (valueIt.hasNext()) { String val = valueIt.next(); Iterator keyIt = mapKeys.iterator(); while (keyIt.hasNext()) { Integer key = keyIt.next(); String comp1 = passedMap.get(key); String comp2 = val; if (comp1.equals(comp2)) { keyIt.remove(); sortedMap.put(key, val); break; } } } return sortedMap; } 

Apenas um exemplo inicial. Desta forma, é mais útil, pois classifica o HashMap e mantém os valores duplicados também.

Tente abaixo o código funciona bem para mim. Você pode escolher tanto a ordem crescente quanto a decrescente

 import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Map.Entry; public class SortMapByValue { public static boolean ASC = true; public static boolean DESC = false; public static void main(String[] args) { // Creating dummy unsorted map Map unsortMap = new HashMap(); unsortMap.put("B", 55); unsortMap.put("A", 80); unsortMap.put("D", 20); unsortMap.put("C", 70); System.out.println("Before sorting......"); printMap(unsortMap); System.out.println("After sorting ascending order......"); Map sortedMapAsc = sortByComparator(unsortMap, ASC); printMap(sortedMapAsc); System.out.println("After sorting descindeng order......"); Map sortedMapDesc = sortByComparator(unsortMap, DESC); printMap(sortedMapDesc); } private static Map sortByComparator(Map unsortMap, final boolean order) { List> list = new LinkedList>(unsortMap.entrySet()); // Sorting the list based on values Collections.sort(list, new Comparator>() { public int compare(Entry o1, Entry o2) { if (order) { return o1.getValue().compareTo(o2.getValue()); } else { return o2.getValue().compareTo(o1.getValue()); } } }); // Maintaining insertion order with the help of LinkedList Map sortedMap = new LinkedHashMap(); for (Entry entry : list) { sortedMap.put(entry.getKey(), entry.getValue()); } return sortedMap; } public static void printMap(Map map) { for (Entry entry : map.entrySet()) { System.out.println("Key : " + entry.getKey() + " Value : "+ entry.getValue()); } } } 

Editar: versão 2

Usado novo recurso java como stream para cada um, etc

O mapa será classificado por chaves se os valores forem os mesmos

  import java.util.*; import java.util.Map.Entry; import java.util.stream.Collectors; public class SortMapByValue { private static boolean ASC = true; private static boolean DESC = false; public static void main(String[] args) { // Creating dummy unsorted map Map unsortMap = new HashMap<>(); unsortMap.put("B", 55); unsortMap.put("A", 20); unsortMap.put("D", 20); unsortMap.put("C", 70); System.out.println("Before sorting......"); printMap(unsortMap); System.out.println("After sorting ascending order......"); Map sortedMapAsc = sortByValue(unsortMap, ASC); printMap(sortedMapAsc); System.out.println("After sorting descending order......"); Map sortedMapDesc = sortByValue(unsortMap, DESC); printMap(sortedMapDesc); } private static Map sortByValue(Map unsortMap, final boolean order) { List> list = new LinkedList<>(unsortMap.entrySet()); // Sorting the list based on values list.sort((o1, o2) -> order ? o1.getValue().compareTo(o2.getValue()) == 0 ? o1.getKey().compareTo(o2.getKey()) : o1.getValue().compareTo(o2.getValue()) : o2.getValue().compareTo(o1.getValue()) == 0 ? o2.getKey().compareTo(o1.getKey()) : o2.getValue().compareTo(o1.getValue())); return list.stream().collect(Collectors.toMap(Entry::getKey, Entry::getValue, (a, b) -> b, LinkedHashMap::new)); } private static void printMap(Map map) { map.forEach((key, value) -> System.out.println("Key : " + key + " Value : " + value)); } } 

No Java 8:

 Map sortedMap = unsortedMap.entrySet().stream() .sorted(Entry.comparingByValue()) .collect(Collectors.toMap(Entry::getKey, Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new)); 

Você não faz basicamente. Um HashMap é fundamentalmente desordenado. Quaisquer padrões que você possa ver na ordem não devem ser confiáveis.

Existem mapas ordenados como o TreeMap , mas eles tradicionalmente ordenam por chave em vez de por valor. É relativamente incomum classificar por valor – especialmente porque várias chaves podem ter o mesmo valor.

Você pode dar mais contexto para o que você está tentando fazer? Se você está realmente apenas armazenando números (como strings) para as teclas, talvez um SortedSet como o TreeSet funcionaria para você?

Como alternativa, você poderia armazenar duas collections separadas encapsuladas em uma única class para atualizar as duas ao mesmo tempo?

 package com.naveen.hashmap; import java.util.*; import java.util.Map.Entry; public class SortBasedonValues { /** * @param args */ public static void main(String[] args) { HashMap hm = new HashMap(); hm.put("Naveen", 2); hm.put("Santosh", 3); hm.put("Ravi", 4); hm.put("Pramod", 1); Set> set = hm.entrySet(); List> list = new ArrayList>( set); Collections.sort(list, new Comparator>() { public int compare(Map.Entry o1, Map.Entry o2) { return o2.getValue().compareTo(o1.getValue()); } }); for (Entry entry : list) { System.out.println(entry.getValue()); } } } 
 map.entrySet().stream() .sorted((k1, k2) -> -k1.getValue().compareTo(k2.getValue())) .forEach(k -> System.out.println(k.getKey() + ": " + k.getValue())); 

Como um tipo de solução simples, você pode usar o TreeMap temporário se precisar apenas de um resultado final:

 TreeMap sortedMap = new TreeMap(); for (Map.Entry entry : map.entrySet()) { sortedMap.put((String) entry.getValue(), (Integer)entry.getKey()); } 

Isso fará com que as strings sejam classificadas como chaves de sortedMap.

Eu estendo um TreeMap e sobrescrevo os methods entrySet () e values ​​(). Chave e valor precisam ser comparáveis.

Siga o código:

 public class ValueSortedMap extends TreeMap { @Override public Set> entrySet() { Set> originalEntries = super.entrySet(); Set> sortedEntry = new TreeSet>(new Comparator>() { @Override public int compare(Entry entryA, Entry entryB) { int compareTo = entryA.getValue().compareTo(entryB.getValue()); if(compareTo == 0) { compareTo = entryA.getKey().compareTo(entryB.getKey()); } return compareTo; } }); sortedEntry.addAll(originalEntries); return sortedEntry; } @Override public Collection values() { Set sortedValues = new TreeSet<>(new Comparator(){ @Override public int compare(V vA, V vB) { return vA.compareTo(vB); } }); sortedValues.addAll(super.values()); return sortedValues; } } 

Testes Unitários:

 public class ValueSortedMapTest { @Test public void basicTest() { Map sortedMap = new ValueSortedMap<>(); sortedMap.put("A",3); sortedMap.put("B",1); sortedMap.put("C",2); Assert.assertEquals("{B=1, C=2, A=3}", sortedMap.toString()); } @Test public void repeatedValues() { Map sortedMap = new ValueSortedMap<>(); sortedMap.put("D",67.3); sortedMap.put("A",99.5); sortedMap.put("B",67.4); sortedMap.put("C",67.4); Assert.assertEquals("{D=67.3, B=67.4, C=67.4, A=99.5}", sortedMap.toString()); } } 

encontrei uma solução, mas não tenho certeza se o mapa tem tamanho grande, útil para casos normais.

  /** * sort HashMap by value * CustomData needs to provide compareTo() for comparing CustomData * @param map */ public void sortHashMapByValue(final HashMap map) { ArrayList keys = new ArrayList(); keys.addAll(map.keySet()); Collections.sort(keys, new Comparator() { @Override public int compare(String lhs, String rhs) { CustomData val1 = map.get(lhs); CustomData val2 = map.get(rhs); if (val1 == null) { return (val2 != null) ? 1 : 0; } else if (val1 != null) && (val2 != null)) { return = val1.compareTo(val2); } else { return 0; } } }); for (String key : keys) { CustomData c = map.get(key); if (c != null) { Log.e("key:"+key+", CustomData:"+c.toString()); } } } 
 package SortedSet; import java.util.*; public class HashMapValueSort { public static void main(String[] args){ final Map map = new HashMap(); map.put(4,"Mango"); map.put(3,"Apple"); map.put(5,"Orange"); map.put(8,"Fruits"); map.put(23,"Vegetables"); map.put(1,"Zebra"); map.put(5,"Yellow"); System.out.println(map); final HashMapValueSort sort = new HashMapValueSort(); final Set> entry = map.entrySet(); final Comparator> comparator = new Comparator>() { @Override public int compare(Map.Entry o1, Map.Entry o2) { String value1 = o1.getValue(); String value2 = o2.getValue(); return value1.compareTo(value2); } }; final SortedSet> sortedSet = new TreeSet(comparator); sortedSet.addAll(entry); final Map sortedMap = new LinkedHashMap(); for(Map.Entry entry1 : sortedSet ){ sortedMap.put(entry1.getKey(),entry1.getValue()); } System.out.println(sortedMap); } } 
 public static TreeMap sortMap(HashMap passedMap, String byParam) { if(byParam.trim().toLowerCase().equalsIgnoreCase("byValue")) { // Altering the (key, value) -> (value, key) HashMap newMap = new HashMap(); for (Map.Entry entry : passedMap.entrySet()) { newMap.put(entry.getValue(), entry.getKey()); } return new TreeMap(newMap); } return new TreeMap(passedMap); } 
 import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map.Entry; public class CollectionsSort { /** * @param args */`enter code here` public static void main(String[] args) { // TODO Auto-generated method stub CollectionsSort colleciotns = new CollectionsSort(); List list = new ArrayList(); HashMap h = new HashMap(); h.put("nayanana", 10); h.put("lohith", 5); for (Entry value : h.entrySet()) { combine a = colleciotns.new combine(value.getValue(), value.getKey()); list.add(a); } Collections.sort(list); for (int i = 0; i < list.size(); i++) { System.out.println(list.get(i)); } } public class combine implements Comparable { public int value; public String key; public combine(int value, String key) { this.value = value; this.key = key; } @Override public int compareTo(combine arg0) { // TODO Auto-generated method stub return this.value > arg0.value ? 1 : this.value < arg0.value ? -1 : 0; } public String toString() { return this.value + " " + this.key; } } }