2017-10-02 3 views
0

J'ai une HashMap qui fait correspondre un caractère à un Integer. Afin de trier par valeur j'ai écrit mon comparateur et j'utilise TreeMap. Mais il me manque la valeur. J'ai vérifié cela pour String "tree". Ma carte 'chars' après pour chaque boucle ressemble à {r = 1, t = 1, e = 2} et tree après putAll (deux lignes plus tard) est {e = 2, r = 1}. Qu'est-ce qui arrive à char 't'? Pourquoi est-ce manqué? Et comment puis-je le changer?Valeur manquante dans une TreeMap après putAll()

class ValueComparator implements Comparator<Character> { 

private Map<Character, Integer> map; 

public ValueComparator(Map<Character, Integer> map) { 
    this.map = map; 
} 

public int compare(Character a, Character b) { 
    return map.get(b).compareTo(map.get(a)); 
} 
} 

public String frequencySort(String s) { 
    if (s.length() <= 1) return s; 

    HashMap<Character,Integer> chars = new HashMap<Character,Integer>(); 
    for(Character c : s.toCharArray()){ 
     if (chars.containsKey(c)){ 
      chars.put(c,chars.get(c)+1); 

     } 
     else { 
      chars.put(c,1); 
     } 
    } 

    TreeMap<Character,Integer> tree = new TreeMap<Character,Integer>(new ValueComparator(chars)); 
    tree.putAll(chars); 

    /** 
    * rest of the code 
    **/ 

} 
+2

Votre comparateur considère "r" et "t'" égal. La carte ne va pas avoir deux entrées pour des clés égales. – user2357112

+0

Je comprends. Mais je ne sais pas quoi faire à ce sujet ... pouvez-vous me donner un indice? – Malvinka

+0

Un choix serait de ne pas utiliser une TreeMap pour faire votre tri. – user2357112

Répondre

2

Votre ValueComparator traite les entrées avec le même nombre que les doublons. Une solution simple est d'utiliser la clé comme départage:

public int compare(Character a, Character b) { 
    int result = map.get(b).compareTo(map.get(a)); 
    return result != 0 ? result : a.compareTo(b); 
} 

Vous pouvez également utiliser les flux pour construire la carte de fréquence, les trier et stocker un ordre LinkedHashMap:

Map<Character, Integer> counts = s.chars() 
     .mapToObj(i -> (char)i) 
     .collect(Collectors.groupingBy(Function.identity(), Collectors.summingInt(c -> 1))) 
     .entrySet() 
     .stream() 
     .sorted(Collections.reverseOrder(Entry.comparingByValue())) 
     .collect(Collectors.toMap(Entry::getKey, Entry::getValue, (a, b) -> b, LinkedHashMap::new));