我有一个将字符映射到整数的HashMap。为了按值排序,我写了比较器,我正在使用TreeMap。但我错过了价值。我检查了字符串“树”。每个循环后我的地图'chars'看起来像{r = 1,t = 1,e = 2},putAll之后的树(后两行)是{e = 2,r = 1}。 char't'发生了什么?为什么错过了?我该如何改变呢?
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
**/
}
答案 0 :(得分:2)
您的ValueComparator
会将与重复次数相同的条目视为条目。一个简单的解决方法是使用密钥作为平局:
public int compare(Character a, Character b) {
int result = map.get(b).compareTo(map.get(a));
return result != 0 ? result : a.compareTo(b);
}
或者,您可以使用流来构建频率图,对其进行排序并将其存储为有序的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));