我实现了一个非常好的排序解决方案,找到了here
static <K,V extends Comparable<? super V>> SortedSet<Map.Entry<K,V>>
entriesSortedByValues(Map<K,V> map) {
SortedSet<Map.Entry<K,V>> sortedEntries = new TreeSet<Map.Entry<K,V>>(
new Comparator<Map.Entry<K,V>>() {
@Override
public int compare(Map.Entry<K,V> e1, Map.Entry<K,V> e2) {
int res = e1.getValue().compareTo(e2.getValue());
return res != 0 ? res : 1;
}
}
);
sortedEntries.addAll(map.entrySet());
return sortedEntries;
}代码看起来很好用。但是,FindBugs抱怨这一行:
sortedEntries.addAll(map.entrySet());申诉是:
com.local.sem.util.MapUtil.entriesSortedByValues(Map)中的Bug:添加条目集的元素可能会因为重用Map.Entry对象而失败 允许entrySet()方法返回基础地图的视图,其中一个条目对象在迭代期间被重用和返回。从Java1.6开始,IdentityHashMap和EnumMap都这样做了。当迭代这样一个Map时,条目值只有在您进入下一个迭代之前才有效。例如,如果您试图将这样的entrySet传递给addAll方法,事情就会变得非常糟糕。 置信度:Normal,Rank:令人不安(14) 模式:DMI_ENTRY_SETS_MAY_REUSE_ENTRY_OBJECTS 类型:DMI,分类:BAD_PRACTICE (不良实践)
有人能告诉我这意味着什么吗?或者它是否真的与这个特定的代码相关?
发布于 2012-08-08 17:59:23
下面是这个问题的一个简单例子:
Map<String,String> map = new IdentityHashMap<String,String>();
map.put("a", "1");
map.put("b", "2");
Iterator<Entry<String,String>> i = map.entrySet().iterator();
Entry<String,String> e1 = i.next();
System.out.println("first key is: " + e1.getKey());
Entry<String,String> e2 = i.next();
System.out.println("first key is now: " + e1.getKey());使用Java 6,这个输出:
first key is: a
first key is now: b这是因为对i.next()的第二个调用与第一个调用返回相同的条目,但它更改了存储在该条目中的值。
如果我将IdentityHashMap更改为HashMap,则返回的每个条目都不同,因此e1.getKey()不会更改。
发布于 2012-08-08 01:56:31
允许entrySet()方法返回基础地图的视图,其中一个条目对象在迭代期间被重用和返回。从Java1.6开始,IdentityHashMap和EnumMap都这样做了。当迭代这样一个Map时,条目值只有在您进入下一个迭代之前才有效。例如,如果您试图将这样的entrySet传递给addAll方法,事情就会变得非常糟糕。
请阅读该链接以获得更多细节。OBJECTS
https://stackoverflow.com/questions/11856391
复制相似问题