Java Carte trier par valeur
J'étais à la recherche de moyens de tri Map<String, Integer>
par des valeurs. J'ai trouvé ce post, qui a résolu mon problème de tri, mais pas exactement. Selon le post, j'ai écrit le code suivant:
import java.util.*;
public class Sort {
static class ValueComparator implements Comparator<String> {
Map<String, Integer> base;
ValueComparator(Map<String, Integer> base) {
this.base = base;
}
@Override
public int compare(String a, String b) {
if (base.get(a) >= base.get(b)) {
return 1;
} else {
return -1;
}
}
}
public static void main(String[] args) {
HashMap<String, Integer> map = new HashMap<String, Integer>();
ValueComparator vc = new ValueComparator(map);
TreeMap<String, Integer> sorted = new TreeMap<String, Integer>(vc);
map.put("A", 1);
map.put("B", 2);
sorted.putAll(map);
for (String key : sorted.keySet()) {
System.out.println(key + " : " + sorted.get(key)); //why null values here?
}
System.out.println(sorted.values()); //But we do have non-null values here!
}
}
De sortie:
A : null
B : null
[1, 2]
BUILD SUCCESSFUL (total time: 0 seconds)
Comme vous pouvez le voir à partir de la sortie, le get
méthode retourne toujours null
. La raison en est mon ValueComparator.compare()
méthode ne retourne jamais 0
, que j'ai trouvé en faisant ce post.
Quelqu'un a suggéré dans ce post suivant pour résoudre le null
problème de valeur:
public int compare(String a, String b) {
if (base.get(a) > base.get(b)) {
return 1;
}else if(base.get(a) == base.get(b)){
return 0;
}
return -1;
}
J'ai testé ce morceau de code, et il introduit une clé de la fusion de problème. En d'autres termes, lorsque les valeurs sont égales les touches correspondantes sont regroupées.
J'ai aussi essayé le suivant:
public int compare(String a, String b) {
if (a.equals(b)) return 0;
if (base.get(a) >= base.get(b)) {
return 1;
} else return -1;
}
Il ne fonctionne pas non plus. Certaines valeurs sont encore null
. En outre, cette solution de contournement peut éventuellement avoir des problèmes de logique.
N'importe qui peut proposer un travail entièrement de solution à mon problème? J'aimerais que la valeur trier par fonction de travail et la get
méthode de travail en même temps.
Comment vous racontez la triées valeurs sur les touches correspondantes? Je ne veux pas entretenir de relation entre la clé et la valeur manuellement.
OK... donc, vous voulez les touches pour être classées selon l'ordre des valeurs. I suppose que je comprends ce que vous voulez maintenant.
Dans ce cas, vous devez utiliser seulement ceci:
return base.get(a).compareTo(base.get(b))
Si vous avez de meilleures solutions que l'aide de cartes, ça serait sympa 🙂
OriginalL'auteur Terry Li | 2012-12-13
Vous devez vous connecter pour publier un commentaire.
Dans votre fonction de comparaison, lorsque les valeurs sont égales, vous devriez ensuite comparer les touches. Cela permettra d'assurer que les différentes clés ayant la même valeur ne peut pas être "fusionnés", parce qu'il disambiguates entrées qui seraient autrement comparer l'égalité.
Par exemple:
(vous aurez besoin de modifier le code ci-dessus pour correspondre à votre politique pour les valeurs null)
Noter que votre approche de tri sur les valeurs est assez fragile, si. Votre "triés" la carte ne prendra pas en charge l'ajout de nouvelles entrées, ce qui pourrait être assez déroutant.
OriginalL'auteur cambecc
Ce code compare boîte
Integer
s par référence.Changer de
base.get(a).equals(base.get(b))
et cela devrait fonctionner.Pourquoi pas?
Ainsi, les Entiers sont autounboxed. Il fonctionne de toute façon.
Non, il n'est pas...
Non, le
==
l'exploitant n'a pas autounbox.OriginalL'auteur SLaks
...
De sortie:
OriginalL'auteur xagyg
Essayez ceci:
Pour démontrer que vous êtes incorrect sur l'auto-unboxing:
Mon résultat est:
Integer
objets directement à l'aide de==
.Non, vous ne pouvez pas.
Bon point! Je ne le savais pas. Mais mon problème persiste même avec la bonne méthode de comparaison 🙁
OriginalL'auteur jahroy