java - FindBugs:DMI_ENTRY_SETS_MAY_REUSE_ENTRY_OBJECTS

标签 java findbugs

我实现了非常好的排序解决方案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/

相关文章:

Java 将公钥和私钥转换为字符串,然后再转换回来

java - 伯克利数据库 GAE

java - Java层捕获JNI异常

java - Findbugs Java 忽略字段或行

java - 在这种情况下,FindBugs 'JLM_JSR166_UTILCONCURRENT_MONITORENTER' 是否可以安全地忽略

java - Spring Boot Maven 项目的垃圾收集从不运行

java - 使用SDk清除azure门户中定义的容器的现有策略后如何上传新创建的sharedAccessPolicy?

java - 变量的 Enum<> 泛型类型的使用

java - 如何使用 findbugs-maven-plugin 生成一份报告?

findbugs - Findbugs 如何检测空的 catch block ?