J'ai une carte qui a des chaînes pour les clés et les valeurs.
Les données sont comme suit:
"question1", "1"
"question9", "1"
"question2", "4"
"question5", "2"
Je veux trier la carte en fonction de ses clés. Donc, au final, j'aurai question1, question2, question3
.... et ainsi de suite.
En fin de compte, j'essaie d'obtenir deux chaînes de cette carte.
À l'heure actuelle, j'ai les éléments suivants:
Iterator it = paramMap.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pairs = (Map.Entry) it.next();
questionAnswers += pairs.getKey() + ",";
}
Cela me donne les questions dans une chaîne, mais elles ne sont pas en ordre.
Utilisez une TreeMap
. C'est précisément ce que c'est.
Si cette carte vous est transmise et que vous ne pouvez pas déterminer le type, vous pouvez alors procéder comme suit:
SortedSet<String> keys = new TreeSet<>(map.keySet());
for (String key : keys) {
String value = map.get(key);
// do something
}
Cela va parcourir la carte dans l'ordre naturel des touches.
Techniquement, vous pouvez utiliser tout ce qui implémente SortedMap
, mais excepté dans de rares cas, cela équivaut à TreeMap
, tout comme utiliser une implémentation Map
équivaut généralement à HashMap
.
Dans les cas où vos clés sont d'un type complexe qui n'implémente pas Comparable ou si vous ne souhaitez pas utiliser l'ordre naturel, TreeMap
et TreeSet
ont des constructeurs supplémentaires qui vous permettent de passer une 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());
Rappelez-vous que lorsque vous utilisez une variable TreeMap
ou TreeSet
, ses performances seront différentes de celles de HashMap
ou HashSet
. En gros, les opérations qui trouvent ou insèrent un élément vont de O(1) à O(Log(N)).
Dans une HashMap
, passer de 1 000 éléments à 10 000 n'affecte pas vraiment le temps nécessaire pour rechercher un élément, mais pour une TreeMap
, le temps de recherche sera environ trois fois plus lent (en supposant que Log2). Passer de 1 000 à 100 000 sera environ 6 fois plus lent pour chaque recherche d'élément.
En supposant que TreeMap ne soit pas bon pour vous (et en supposant que vous ne pouvez pas utiliser de génériques):
List sortedKeys=new ArrayList(yourMap.keySet());
Collections.sort(sortedKeys);
// Do what you need with sortedKeys.
En utilisant TreeMap
, vous pouvez trier la carte.
Map<String, String> map = new HashMap<>();
Map<String, String> treeMap = new TreeMap<>(map);
for (String str : treeMap.keySet()) {
System.out.println(str);
}
Utilisez un TreeMap !
Si vous avez déjà une carte et souhaitez la trier sur des clés, utilisez simplement:
Map<String, String> treeMap = new TreeMap<String, String>(yourMap);
Un exemple de travail complet:
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
Il suffit d'utiliser TreeMap
new TreeMap<String, String>(unsortMap);
Sachez que la TreeMap est triée selon l'ordre naturel de ses 'clés'
Si vous ne pouvez pas utiliser TreeMap
, dans Java 8, nous pouvons utiliser la méthode toMap () dans Collectors
qui prend les paramètres suivants:
Exemple Java 8
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));
Nous pouvons modifier l'exemple pour utiliser un comparateur personnalisé et pour trier sur la base des clés comme suit:
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));
Utilisation de 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));
Ce code peut trier une carte clé-valeur dans les deux ordres, à savoir croissant et décroissant.
<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;
}
Par exemple:
Map<Integer,Double> recommWarrVals = new HashMap<Integer,Double>();
recommWarrVals = sortByValues(recommWarrVals, 1); // Ascending order
recommWarrVals = sortByValues(recommWarrVals,-1); // Descending order
Pour trier un Map<K, V>
par clé, placez les clés dans un List<K>
:
List<K> result = map.keySet().stream().sorted().collect(Collectors.toList());
Pour trier un Map<K, V>
par clé, en plaçant les entrées dans un List<Map.Entry<K, V>>
:
List<Map.Entry<K, V>> result =
map.entrySet()
.stream()
.sorted(Map.Entry.comparingByKey())
.collect(Collectors.toList());
Dernier point mais non le moindre: pour trier strings en fonction des paramètres régionaux - utilisez une classe Collator (comparateur):
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());
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);
}
Nous pouvons également trier la clé en utilisant la méthode Arrays.sort.
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);
}
Dans un style fonctionnel sera comme ci-dessous:
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);
Sortie:
question 1
question 2
question5
question9
En Java 8, vous pouvez également utiliser .stream (). Sorted ():
myMap.keySet().stream().sorted().forEach(key -> {
String value = myMap.get(key);
System.out.println("key: " + key);
System.out.println("value: " + value);
}
);