Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/377.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java FindBugs:DMI\u ENTRY\u set\u可以\u重用\u ENTRY\u对象_Java_Findbugs - Fatal编程技术网

Java FindBugs:DMI\u ENTRY\u set\u可以\u重用\u ENTRY\u对象

Java FindBugs:DMI\u ENTRY\u set\u可以\u重用\u ENTRY\u对象,java,findbugs,Java,Findbugs,我实现了非常好的排序解决方案,发现: 投诉是: 错误:添加条目集的元素可能会由于重复使用 中的Map.Entry对象 com.local.sem.util.MapUtil.entriesSortedByValues(地图) 允许entrySet()方法返回底层对象的视图 在映射过程中重用并返回单个条目对象的映射 迭代。从Java1.6开始,IdentityHashMap和EnumMap都这样做了。 在遍历此类映射时,条目值仅在 您可以前进到下一个迭代。例如,如果您试图通过 如果将这样的入口设置为

我实现了非常好的排序解决方案,发现:

投诉是:

错误:添加条目集的元素可能会由于重复使用 中的Map.Entry对象 com.local.sem.util.MapUtil.entriesSortedByValues(地图)

允许entrySet()方法返回底层对象的视图 在映射过程中重用并返回单个条目对象的映射 迭代。从Java1.6开始,IdentityHashMap和EnumMap都这样做了。 在遍历此类映射时,条目值仅在 您可以前进到下一个迭代。例如,如果您试图通过 如果将这样的入口设置为addAll方法,则会出现严重错误

自信:正常,排名:令人不安(14)
模式:DMI\u ENTRY\u set\u可以重用\u ENTRY\u对象
类型:DMI,类别:不良实践(不良实践)

有谁能告诉我这是什么意思,或者它是否真的与这段特定代码相关吗?

entrySet()方法可以返回一个底层映射的视图,在该视图中,一个条目对象被重用并在迭代过程中返回。从Java1.6开始,IdentityHashMap和EnumMap都这样做了。当在这样的映射中迭代时,条目值仅在您进入下一次迭代之前有效。例如,如果您试图将这样一个entrySet传递给addAll方法,那么事情就会大错特错


请阅读链接了解更多详细信息

下面是一个简单的问题示例:

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());
这是因为对i.next()的第二个调用返回与第一个相同的条目,但它更改了该条目中存储的值


如果我将IdentityHashMap更改为HashMap,则返回的每个条目都是不同的,因此e1.getKey()不会更改。

Ok。我现在完全理解这个概念。例如,谢谢。然而,在实践中,我还没有发现这是真的。我使用HashMap、Hashtable、IdentityHashMap、LinkedHashMap、Properties、TreeMap和WeakHashMap运行了您的代码,每次我都为这两个输出获得相同的值。我正在使用Java7。这会有什么不同吗?是的,我看到了与Java7相同的事情。因此,他们一定在Java 7中再次更改了entrySet()的实现。在Java6中,EntryIterator.next总是返回相同的对象(迭代器本身)。在Java7中,EntryIterator.next总是返回下一个Entry对象。感谢您的分析。我用Java6重新运行了代码,并确认结果是不同的。我现在完全明白FindBugs在抱怨什么了。但就我的具体例子而言,我并不完全确定我应该做什么。看起来我使用Java 7是安全的,但是如果API规范允许重用Map.Entry,理想情况下,我不希望我的代码与未来版本的Java或其他JVM冲突。我应该让代码保持原样并希望达到最佳状态,还是应该以某种方式对其进行修改以防止将来的灾难?也许我不应该使用
addAll
,而是应该迭代
entrySet
,使用
new AbstractMap.SimpleImmutableEntry(entry.getKey(),entry.getValue())为每个条目创建一个防御性副本
,然后添加该副本。这是findbug网站上的一个非常简单且很好的解释,我以为你没有读过。。
sortedEntries.addAll(map.entrySet());
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());
first key is: a
first key is now: b