Kaip rūšiuoti žemėlapio reikšmes raktu Java?

Turiu žemėlapį, kuriame yra raktų ir reikšmių.

Duomenys yra panašūs į šiuos:

"klausimas1", "1"
"Klausimas9", "1"
„2 klausimas“, „4“
„5 klausimas“, „2“

Noriu rūšiuoti žemėlapį raktais. Taigi pabaigoje turėsiu 1 question1, question2, question3 ir pan.


Galų gale, aš bandau gauti dvi eilutes iš šios kortelės.

  • Pirmoji eilutė: klausimai (nuo 1 iki 10)
  • Antroji eilutė: atsakymai (ta pačia tvarka kaip ir klausimas)

Šiuo metu turiu:

 Iterator it = paramMap.entrySet().iterator(); while (it.hasNext()) { Map.Entry pairs = (Map.Entry) it.next(); questionAnswers += pairs.getKey() + ","; } 

Tai suteikia man klausimų, tačiau jie nėra tinkami.

317
28 мая '09 в 21:43 2009-05-28 21:43 yra nustatytas n00bstackie gegužės 28, '09, 21:43 2009-05-28 21:43
@ 14 atsakymų

Trumpas atsakymas

Naudokite „ TreeMap . Būtent tai yra.

Jei ši kortelė jums suteikiama ir negalite nustatyti tipo, galite atlikti šiuos veiksmus:

 SortedSet<String> keys = new TreeSet<>(map.keySet()); for (String key : keys) { String value = map.get(key); // do something } 

Tai praeis per žemėlapį natūralia raktų tvarka.


Ilgesnis atsakymas

Techniškai, jūs galite naudoti viską, ką „ SortedMap įgyvendina, tačiau, išskyrus retus atvejus, tai yra lygiavertė „ TreeMap , lygiai taip pat, kaip naudojant „ Map paprastai tai atitinka „ HashMap .

Tais atvejais, kai raktai yra sudėtingas tipas, kuris neįgyvendina palyginamojo, arba nenorite naudoti natūralios tvarkos, tada „ TreeMap ir „ TreeSet turi papildomų konstruktorių, kurie leidžia jums perduoti Comparator :

 // placed inline for the demonstration, but doesn't have to be a lambda expression Comparator<Foo> comparator = (Foo o1, Foo o2) -> { ... } SortedSet<Foo> keys = new TreeSet<>(comparator); keys.addAll(map.keySet()); 

Atminkite, kad naudojant „ TreeMap arba „ TreeSet jis turės skirtingas charakteristikas nei „ HashMap ar „ HashSet . Apibendrinant, operacijos, kurios suranda ar įdeda elementą, pereis nuo O (1) į O (žurnalas (N)) .

HashMap perėjimas iš 1000 elementų į 10000 iš tikrųjų neturi įtakos jūsų elemento paieškos laikotarpiui, bet „ TreeMap “ paieškos laikas bus maždaug 3 kartus lėčiau (darant prielaidą, kad TreeMap 2 ). Perėjimas nuo 1000 iki 100 000 kiekvienam paieškos elementui bus maždaug 6 kartus mažesnis.

558
28 мая '09 в 21:43 2009-05-28 21:43 Atsakymą pateikė Jherico gegužės 28 d. , 09:21 , 2009-05-28 21:43

Darant prielaidą, kad „TreeMap“ jums netinka (ir jei negalite naudoti generinių vaistų):

border=0
 List sortedKeys=new ArrayList(yourMap.keySet()); Collections.sort(sortedKeys); // Do what you need with sortedKeys. 
126
28 мая '09 в 22:03 2009-05-28 22:03 atsakymą pateikė „ TrayMan“ gegužės 28 d., 09.00 val. 22.00 val. 2009-05-28 22:03

Su „ TreeMap “ pagalba galite rūšiuoti žemėlapį.

 Map<String, String> map = new HashMap<>(); Map<String, String> treeMap = new TreeMap<>(map); for (String str : treeMap.keySet()) { System.out.println(str); } 
48
07 нояб. Atsakymą pateikė Manoj Singh, lapkričio 7 d. 2011-11-07 14:51 '11 at 14:51 pm 2011-11-07 14:51

Naudokite „ TreeMap“ !

34
28 мая '09 в 21:44 2009-05-28 21:44 atsakymą pateikė „ AgileJon “ gegužės 28 d. , 09:21 , 2009-05-28 21:44

Jei jau turite žemėlapį ir norite jį surūšiuoti pagal raktus, tiesiog naudokite:

 Map<String, String> treeMap = new TreeMap<String, String>(yourMap); 

Visas darbo pavyzdys:

 import java.util.HashMap; import java.util.Set; import java.util.Map; import java.util.TreeMap; import java.util.Iterator; class SortOnKey { public static void main(String[] args) { HashMap<String,String> hm = new HashMap<String,String>(); hm.put("3","three"); hm.put("1","one"); hm.put("4","four"); hm.put("2","two"); printMap(hm); Map<String, String> treeMap = new TreeMap<String, String>(hm); printMap(treeMap); }//main public static void printMap(Map<String,String> map) { Set s = map.entrySet(); Iterator it = s.iterator(); while ( it.hasNext() ) { Map.Entry entry = (Map.Entry) it.next(); String key = (String) entry.getKey(); String value = (String) entry.getValue(); System.out.println(key + " => " + value); }//while System.out.println("========================"); }//printMap }//class 
32
21 авг. atsakymas pateikiamas MD 21 rug. 2013-08-21 08:58 '13, 08:58, 2013-08-21 08:58

Tiesiog naudokite treemap

 new TreeMap<String, String>(unsortMap); 

Atminkite, kad medžio žemėlapis yra surūšiuotas pagal natūralią „raktų“ tvarką

28
18 февр. Atsakyti Aliti Feb 18 2015-02-18 17:37 '15, 17:37 2015-02-18 17:37

Darant prielaidą, kad negalite naudoti „ TreeMap , „ Java“ 8 sistemoje mes galime naudoti „ ToMap“ () metodą „ Collectors ( Collectors kuris naudoja šiuos parametrus:

  • keymapper : kartografavimo funkcija raktams sukurti
  • valuemapper : rodymo funkcija, skirta vertėms gauti
  • mergeFunction : sujungimo funkcija naudojama norint išspręsti su tuo pačiu raktu susijusių reikšmių susidūrimus
  • mapSupplier : funkcija, kuri grąžina naują tuščią žemėlapį, į kurį bus įtraukti rezultatai.

„Java 8“ pavyzdys

 Map<String,String> sample = new HashMap<>(); // push some values to map Map<String, String> newMapSortedByKey = sample.entrySet().stream() .sorted(Map.Entry.<String,String>comparingByKey().reversed()) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new)); Map<String, String> newMapSortedByValue = sample.entrySet().stream() .sorted(Map.Entry.<String,String>comparingByValue().reversed()) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1,e2) -> e1, LinkedHashMap::new)); 

Mes galime pakeisti pavyzdį, kad galėtume naudoti savo palyginamąjį ir surūšiuoti pagal raktą taip:

 Map<String, String> newMapSortedByKey = sample.entrySet().stream() .sorted((e1,e2) -> e1.getKey().compareTo(e2.getKey())) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1,e2) -> e1, LinkedHashMap::new)); 
12
17 нояб. atsakymas pateikiamas i_am_zero 17 nov. 2016-11-17 11:21 '16 at 11:21 2016-11-17 11:21

Naudojant „ Java 8“:

 Map<String, Integer> sortedMap = unsortMap.entrySet().stream() .sorted(Map.Entry.comparingByKey()) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (oldValue, newValue) -> oldValue, LinkedHashMap::new)); 
6
01 мая '18 в 20:52 2018-05-01 20:52 Atsakymą pateikė Taras Melnyk gegužės 18 d., 18 val. 20:52 2018-05-01 20:52

Šis kodas gali rūšiuoti raktų vertės žemėlapį abiejuose užsakymuose, ty didėjimo ir mažėjimo tvarka.

 <K, V extends Comparable<V>> Map<K, V> sortByValues (final Map<K, V> map, int ascending) { Comparator<K> valueComparator = new Comparator<K>() { private int ascending; public int compare(K k1, K k2) { int compare = map.get(k2).compareTo(map.get(k1)); if (compare == 0) return 1; else return ascending*compare; } public Comparator<K> setParam(int ascending) { this.ascending = ascending; return this; } }.setParam(ascending); Map<K, V> sortedByValues = new TreeMap<K, V>(valueComparator); sortedByValues.putAll(map); return sortedByValues; } 

Pavyzdžiui:

 Map<Integer,Double> recommWarrVals = new HashMap<Integer,Double>(); recommWarrVals = sortByValues(recommWarrVals, 1); // Ascending order recommWarrVals = sortByValues(recommWarrVals,-1); // Descending order 
5
24 нояб. Atsakymą pateikė M. Mashaye 24 lapkričio. 2015-11-24 23:56 '15, 11:56 pm 2015-11-24 23:56

„Java“ 8

Jei norite rūšiuoti Map<K, V> pagal raktą, įdėdami raktus į List<K> :

 List<K> result = map.keySet().stream().sorted().collect(Collectors.toList()); 

Jei norite rūšiuoti Map<K, V> raktu, List<Map.Entry<K, V>> įrašus List<Map.Entry<K, V>> :

 List<Map.Entry<K, V>> result = map.entrySet() .stream() .sorted(Map.Entry.comparingByKey()) .collect(Collectors.toList()); 

Paskutinis, bet ne mažiau svarbus dalykas - surūšiuoti eilutes pagal kalbą, naudokite Collator klasę (lyginamąjį):

 Collator collator = Collator.getInstance(Locale.US); collator.setStrength(Collator.PRIMARY); // case insensitive collator List<Map.Entry<String, String>> result = map.entrySet() .stream() .sorted(Map.Entry.comparingByKey(collator)) .collect(Collectors.toList()); 
4
14 апр. Atsakymas pateikiamas Oleksandr 14 balandžio. 2018-04-14 19:22 '18, 19:22 pm 2018-04-14 19:22
 List<String> list = new ArrayList<String>(); Map<String, String> map = new HashMap<String, String>(); for (String str : map.keySet()) { list.add(str); } Collections.sort(list); for (String str : list) { System.out.println(str); } 
1
07 нояб. Atsakymą pateikė Manoj Singh, lapkričio 7 d. 2011-11-07 14:34 '11 at 14:34 2011-11-07 14:34

Taip pat galime rūšiuoti raktą naudodami Arrays.sort metodą.

 Map<String, String> map = new HashMap<String, String>(); Object[] objArr = new Object[map.size()]; for (int i = 0; i < map.size(); i++) { objArr[i] = map.get(i); } Arrays.sort(objArr); for (Object str : objArr) { System.out.println(str); } 
0
07 нояб. Atsakymą pateikė Manoj Singh, lapkričio 7 d. 2011-11-07 14:37 '11 prie 14:37 2011-11-07 14:37

„Java 8“ taip pat galite naudoti .stream (). Rūšiuota ():

 myMap.keySet().stream().sorted().forEach(key -> { String value = myMap.get(key); System.out.println("key: " + key); System.out.println("value: " + value); } ); 
0
06 февр. Atsakymą pateikė Jonas_Hess 06 vasaris. 2018-02-06 19:26 '18 at 19:26 pm 2018-02-06 19:26

Funkciniu stiliumi bus taip:

  Map<String , String> nameMap = new HashMap<>(); nameMap.put("question1","1"); nameMap.put("question9","1"); nameMap.put("question2","4"); nameMap.put("question5","2"); nameMap.entrySet().stream() .sorted(Comparator.comparing(x->x.getKey())) .map(x->x.getKey()) .forEach(System.out::println); 
0
01 февр. Atsakymą pateikė Bendrasis žmogus 01 vasaris. 2019-02-01 14:35 '19, 14:35 pm 2019-02-01 14:35