I need to get a collection from the java HashMap without the changes in the map reflecting in the collection later . I wanted to use Collection.toArray() to achieve this , but its not working . The resultant Object[] is also changing (javadocs say that The returned array will be "safe" in that no references to it are maintained by this collection ) . Any simple way to achieve this?
-
I did not clearly understand what you're trying to achive. But is LinkedHashMap what you're looking for? – batbaatar Jan 28 '12 at 05:48
-
No..the order of insertion is not what i am looking for . lets say we have HashMap of
. the Hashmap.values() would return me a collection – sanre6 Jan 28 '12 at 05:54.Now any changes in the HashMap are being reflected in this collection as well which is the default behaviour .But ,i need a fixed collection where any changes in the map wont be reflected -
@sanre6 Do you mean changes to *items* (objects) contained the HashMap, by chance? – Jan 28 '12 at 06:16
5 Answers
Its not possible to do this with a single API call, you need to utilize deep cloning. Clones won't be changed when you make changes to the original. This topic has been discussed on SO before, see How to clone ArrayList and also clone its contents? and Deep clone utility recomendation.

- 1
- 1

- 50,430
- 22
- 93
- 142
-
I think this answer could be expanded: what is meant by a "deep clone" and how does this prevent modifications or "shared references"? A link might be useful... – Jan 28 '12 at 06:14
-
Google collections Immutable Map may help you.
see Collections.unmodifiableMap also

- 8,360
- 3
- 30
- 40
-
2
-
1I believe the Google collections Immutable Map is what the OP is looking for. @pst: My reading of the documentation leads me to believe that the objects contained in com.google.common.collect.ImmutableMap are immutable. – Justin Muller Jan 28 '12 at 06:21
-
1
-
2@JustinMuller I do not believe it interpretation is correct. It says nothing about the immutability of `K` (the only way this can be achieved in Java is with a copy/clone of the objects of type K added). It argues it is different from `unmodifiableMap` -- which will throw an exception of `put` -- but *will still* show new keys via `keys` (e.g.) if the *original* (backing) Map is modified; the documentation makes it sounds like this is *the* difference. – Jan 28 '12 at 06:31
-
That is, think of if "unmodifiableMap" was instead called "readonlyViewOfMap". – Jan 28 '12 at 06:36
-
3If the original backing map is modified (e.g. via put), then the ImmutableMap copy will not reflect the new changes. (If K represents a mutable type, you're already doing something terribly, terribly wrong.) – Louis Wasserman Jan 28 '12 at 09:00
-
3Note that this answer links to the "google-collections" project, which was abandoned more than 2 years ago. See http://guava-libraries.googlecode.com – Kevin Bourrillion Jan 29 '12 at 16:14
You can create an unmodifiable Map

- 1,283
- 13
- 21
-
-
2Not to mention changes in the original map are reflected in the copy. – Perception Jan 28 '12 at 06:16
-
I believe Justin is right. the `unmodifiableMap` method would return a read-only view of the map that would reflect any changes to the base container and sanre6 did not specify that the contained objects should be imnmutable, only that the map should be. – Francois Jan 28 '12 at 07:00
The following is still valid and describes the issue observed (see the bit on what sort of copy is performed). I do not, however, provide any answer on how to perform a deep-copy.
Instead, my suggestion, is to design the objects to be immutable, which avoids this issue entirely. In my experience this works really well for most trivial objects (that is, objects which are not "containers") and can simplify code and reasoning about it.
From the Javadoc for HashMap.values
:
Returns a Collection view of the values contained in this map. The collection is backed by the map, so changes to the map are reflected in the collection, and vice-versa...
Perhaps it would be beneficial to create a copy of it?
HashMap<K,V> map = ....;
List<V> values = new ArrayList<V>(map.values());
That, in essence, performs a shallow-copy that is "now separate". However, being a shallow copy, no clone/copy of the contained objects is performed. (See βнɛƨн Ǥʋяʋиɢ's answer if deep-copy semantics are desired: the question itself seems a little vague on the matter.)
Happy coding
-
i did the same , this doesn't work . The changes are being reflected in the new List as well – sanre6 Jan 28 '12 at 06:24
-
@sanre6 By "changes" to do you mean "changes to *the objects **in** the collection*"? (As opposed to "changes to *the collection*".) If so, see the links to shallow/deep copies, which explain the observed behavior, and the answer from βнɛƨн Ǥʋяʋиɢ. – Jan 28 '12 at 06:25
-
-
-
-
1@sanre6 I would personally make the object themselves *immutable* by contract. Removing mutability of objects can entire negate issues like this: no copy required, because *you can't change it*. This works *really well* for "simple objects". – Jan 28 '12 at 06:50
Create a shallow copy of the original map whith HashMap.clone()
, then retrieve the values colleation from that. This will create new references to the objects in the original map at the time of the clone()
call; obviously changes inside the contained objects themselves will still be reflected in the copied collection. If you want this behaviour, your only way is to hard copy the map objects in your desired collection.

- 18,864
- 6
- 70
- 95