问题描述
我一直在寻找按值对 Map
进行排序的方法.我发现 这篇文章,其中解决了我的排序问题,但不完全是.根据帖子,我写了以下代码:
I was looking for ways of sorting Map<String, Integer>
by values. I found this post, which solved my sorting problem, but not exactly. According to the post, I wrote the following code:
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!
}
}
输出:
A : null
B : null
[1, 2]
BUILD SUCCESSFUL (total time: 0 seconds)
从输出中可以看出,get
方法总是返回 null
.原因是我的 ValueComparator.compare()
方法永远不会返回 0
,这是我通过制作 这篇文章.
As you can see from the output, the get
method always returns null
. The reason is my ValueComparator.compare()
method never returns 0
, which I've figured out by making this post.
有人在那篇文章中建议以下解决 null
值问题:
Someone suggested in that post the following to solve the null
value problem:
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;
}
我已经测试了这段代码,它引入了一个关键的合并问题.换句话说,当值相等时,它们对应的键被合并.
I've tested this piece of code and it introduces a key merging problem. In other words, when the values are equal their corresponding keys are merged.
我还尝试了以下方法:
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;
}
它也不起作用.一些值仍然是 null
.此外,这种解决方法可能存在逻辑问题.
It does not work either. Some of the values are still null
. Besides, this workaround might potentially have logical problems.
任何人都可以为我的问题提出一个完全可行的解决方案吗?我希望按值排序函数和 get
方法同时工作.
Anyone can propose a fully working solution to my problem? I'd like the sort by value function to work and the get
method to work at the same time.
推荐答案
在你的比较函数中,当值相等时,你应该比较键.这将确保具有相同值的不同键不会被合并",因为它消除了原本会比较相等的条目的歧义.
In your compare function, when the values are equal, you should then compare the keys. This will ensure that different keys having the same value will not be "merged", because it disambiguates entries that would otherwise compare equal.
例如:
@Override
public int compare(String a, String b) {
Integer x = base.get(a);
Integer y = base.get(b);
if (x.equals(y)) {
return a.compareTo(b);
}
return x.compareTo(y);
}
(您需要修改上面的代码以匹配您的空值策略)
(you'll need to modify the code above to match your policy for null values)
请注意,您对值进行排序的方法非常脆弱.您的排序"地图将不支持添加新条目,这可能会让人很困惑.
Note that your approach of sorting on values is pretty fragile, though. Your "sorted" map will not support addition of new entries, which could be pretty confusing.
这篇关于Java Map 按值排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!