我实现了非常好的排序解决方案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());
投诉内容是:
Bug: Adding elements of an entry set may fail due to reuse of Map.Entry object in com.local.sem.util.MapUtil.entriesSortedByValues(Map)
The entrySet() method is allowed to return a view of the underlying Map in which a single Entry object is reused and returned during the iteration. As of Java 1.6, both IdentityHashMap and EnumMap did so. When iterating through such a Map, the Entry value is only valid until you advance to the next iteration. If, for example, you try to pass such an entrySet to an addAll method, things will go badly wrong.
Confidence: Normal, Rank: Troubling (14)
Pattern: DMI_ENTRY_SETS_MAY_REUSE_ENTRY_OBJECTS
Type: DMI, Category: BAD_PRACTICE (Bad practice)
谁能告诉我这意味着什么,或者它是否真的与这个特定的代码相关?
最佳答案
这是问题的一个简单示例:
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() 返回与第一次相同的 Entry,但它更改了存储在该 Entry 中的值。
如果我将 IdentityHashMap 更改为 HashMap,则返回的每个 Entry 都不同,因此 e1.getKey() 不会更改。
关于java - FindBugs:DMI_ENTRY_SETS_MAY_REUSE_ENTRY_OBJECTS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11856391/