|
Quick Lists
|
|
Bug ID:
|
6312706
|
|
Votes
|
2
|
|
Synopsis
|
(coll) Map entrySet iterators should return different entries on each call to next()
|
|
Category
|
java:classes_util
|
|
Reported Against
|
|
|
Release Fixed
|
|
|
State
|
6-Fix Understood,
bug
|
|
Priority:
|
4-Low
|
|
Related Bugs
|
6197726
,
6232484
|
|
Submit Date
|
18-AUG-2005
|
|
Description
|
Some Map implementations have an entrySet() method returning a set
with an iterator method returning an iterator which returns the
same (as in customer identity) Map.Entry on each call to next().
This works well in the usual case where each entry is discarded
(effectively becomes garbage) before next() is called.
However, if entries are saved, perhaps to build up other collections or
arrays, they will need to be defensively copied by the caller before next()
is called. This is an optimization to prevent garbage being generated on each
call to next(). However, the cost of creating many small short-lived objects is much
lower than it used to be in most implementations, and is likely to get even lower as VM
optimizations such as escape analysis and stack allocation are implemented.
Therefore such error-prone optimizations such as this one should be removed at
some point.
Posted Date : 2005-08-18 03:30:42.0
|
|
Work Around
|
N/A
|
|
Evaluation
|
The obvious fix of returning a new Map.Entry from each call to
next() should be implemented, some microbenchmarks run,
and the decision as to whether to switch in mustang or dolphin
should be made on that basis.
Posted Date : 2005-08-18 03:33:23.0
|
|
Comments
|
Submitted On 27-SEP-2006
John_P_Black
Breaks Hibernate 2.0.1.
Submitted On 17-OCT-2007
I'm aware of IdentityHashMap and ConcurrentHashMap using this trick, perhaps others as well. It is pretty evil, really.
Submitted On 27-JAN-2009
I just got bit by this on EnumMap.
Note that all you have to do is something innocuous like 'new HashSet(enumMap.entrySet())'. As simple as that, you have a corrupted hash set.
Submitted On 11-JUN-2009
AlexMiller
A simple and surprising test case:
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
public class EntrySetSize {
public static void main(String[] args) {
printSetSize(new ConcurrentHashMap());
printSetSize(new HashMap());
}
private static void printSetSize(Map map) {
map.put("hello", "world");
map.put("world", "hello");
Set set = new HashSet(map.entrySet());
System.out.print(set.size() + " ");
}
}
PLEASE NOTE: JDK6 is formerly known as Project Mustang
|
|
|
 |