我试图通过执行这个循环来获取TreeMap的前10个元素:
TreeMap<Integer, Integer> sortedMap = sortMap(m);
String outString = "";
int count = 10;
while (count > 0) {
count--;
Integer k = sortedMap.firstKey();
outString += String.valueOf(k);
sortedMap.remove(k);
if (count != 0) {
outString += ",";
}
}
System.out.println("outVal is " + outVal);
这会打印outVal is 11377,11377,11377,11377,11377,11377,11377,11377,11377,11377
Integer
实施Comparable
,那么为什么remove
无法正常工作?
更新以下是我的sortMap
实施:
public static TreeMap<Integer, Integer> sortMap(HashMap<Integer, Integer> map) {
ValueComparator bvc = new ValueComparator(map);
TreeMap<Integer,Integer> sorted_map = new TreeMap<Integer,Integer>(bvc);
sorted_map.putAll(map);
return sorted_map;
}
class ValueComparator implements Comparator<Integer> {
java.util.Map<Integer, Integer> base;
public ValueComparator(java.util.Map<Integer, Integer> base) {
this.base = base;
}
// Note: this comparator imposes orderings that are inconsistent with equals.
public int compare(Integer a, Integer b) {
if (base.get(a) >= base.get(b)) {
return -1;
} else {
return 1;
} // returning 0 would merge keys
}
}
更新这很有用:Java Map sort by value。
答案 0 :(得分:5)
public int compare(Integer a, Integer b) {
if (base.get(a) >= base.get(b)) {
return -1;
} else {
return 1;
} // returning 0 would merge keys
}
这个比较器存在缺陷(除了它与equals
不一致外)它不符合比较器合同,该合同规定compare(a,b) > 0
暗示compare(b,a) < 0
,反之亦然。由于TreeMap
依赖于比较器返回0来找到你试图remove()
的密钥,它将永远无法移除任何东西 - 无论你尝试什么密钥并且搜索地图都不会想到密钥存在。
答案 1 :(得分:4)
编辑后很明显,您的自定义比较器是罪魁祸首。你真正想要实现的是在地图中收集十个最高值的键。
但是,如果我可以说,你的方法是不必要的迂回。您已经有了一些地图m
,这是您的起点。所以你需要的只是收集它的entrySet
,按值排序,并采取前十个元素:
import java.util.Map.Entry;
final List<Entry<Integer,Integer>> list = new ArrayList<>(m.entrySet());
Collections.sort(list, new Comparator<Entry<Integer, Integer>>() {
@Override public int compare(Entry<Integer, Integer> o1, Entry<Integer, Integer> o2) {
return o1.getValue().compareTo(o2.getValue());
}});
final StringBuilder b = new StringBuilder();
String delimiter = "";
for (Entry<Integer, Integer> e : list.subList(0, 10)) {
b.append(delimiter).append(e.getKey());
delimiter = ",";
}
System.out.println(b);
请注意,一次性排序比将元素逐个插入二叉搜索树更有效。
我也在使用StringBuilder
,这比在每一步中重新创建一个完整的String
更有效。
答案 2 :(得分:0)
我试着跟着它为我工作
TreeMap<Integer, Integer> sortedMap = new TreeMap<>();
String outString = "";
sortedMap.put(1, 10);
sortedMap.put(2, 20);
sortedMap.put(3, 30);
sortedMap.put(4, 40);
sortedMap.put(5, 50);
int count = 5;
while (count > 0) {
count--;
Integer k = sortedMap.firstKey();
outString += sortedMap.get(k);//String.valueOf(k);
sortedMap.remove(k);
if (count != 0) {
outString += ",";
}
}
System.out.println("outVal is " + outString);
System.out.println(sortedMap.size());