Ordinamento di HashMap in base ai valori

Ho bisogno di ordinare la mia HashMap base ai valori memorizzati al suo interno. HashMap contiene il nome dei contatti memorizzati nel telefono.

Inoltre ho bisogno che le chiavi vengano automaticamente ordinate non appena ordino i valori, o puoi dire che le chiavi e i valori sono legati insieme, quindi qualsiasi cambiamento nei valori dovrebbe riflettersi nelle chiavi.

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

Uscita richiesta:

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

Supponendo che Java, potresti ordinare hashmap in questo modo:

 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; } 

Solo un esempio d’inizio. In questo modo è più utile in quanto ordina la HashMap e mantiene anche i valori duplicati.

Prova sotto il codice funziona bene per me. È ansible scegliere sia l’ordine crescente che quello 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()); } } } 

Modifica: versione 2

Utilizzate nuove funzionalità java come stream per-each ecc

La mappa verrà ordinata per chiavi se i valori sono gli stessi

  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)); } } 

In Java 8:

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

Non lo fai, fondamentalmente. Una HashMap è fondamentalmente non ordinata. Tutti i modelli che potresti vedere nell’ordinazione non dovrebbero essere invocati.

Ci sono mappe ordinate come TreeMap , ma tradizionalmente ordinate per chiave piuttosto che per valore. È relativamente inusuale ordinare per valore, soprattutto perché più chiavi possono avere lo stesso valore.

Puoi dare più contesto per ciò che stai cercando di fare? Se in realtà memorizzi solo numeri (come stringhe) per le chiavi, forse un SortedSet come TreeSet potrebbe funzionare per te?

In alternativa, è ansible memorizzare due raccolte separate incapsulate in una singola class per aggiornarle entrambe contemporaneamente?

 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())); 

Come una sorta di soluzione semplice puoi usare Temp TreeMap se hai bisogno solo di un risultato finale:

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

Questo ti porterà ad avere le stringhe ordinate come chiavi di SortMap.

Estendo una TreeMap e sovrascrivo i metodi entrySet () e values ​​(). Chiave e valore devono essere comparabili.

Segui il codice:

 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; } } 

Test unitari:

 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()); } } 

trovato una soluzione ma non sono sicuro delle prestazioni se la mappa ha dimensioni grandi, utile per casi normali.

  /** * 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; } } }