7

The question is pretty much self-explanatory. I have a data structure (I mentioned a HashMap but it could be a Set or a List also) which I initially populate:

Map<String, String> map = new HashMap<String, String>();

for( something ) {
  map.put( something );
}

After the structure has been populated, I never want to add or delete any items:

map.freeze();

How could one achieve this using standard Java libraries?

Roman C
  • 49,761
  • 33
  • 66
  • 176
gdiazc
  • 2,108
  • 4
  • 19
  • 30
  • If you are always populating it directly after initializing, why not use static initialization? [Here](http://stackoverflow.com/questions/507602/how-to-initialise-a-static-map-in-java) is a good example of how to do that. – colti Jun 11 '13 at 19:09

4 Answers4

20

The best you can do with standard JDK libraries is Collections.unmodifiableMap().

Note that you must drop the original map reference, because that reference can still be accessed and changed normally. If you passed the old reference to any other objects, they still will be able to change your map.

Best practice:

map = Collections.unmodifiableMap(map);

and make sure you didn't share the original map reference.

Petr Janeček
  • 37,768
  • 12
  • 121
  • 145
  • 4
    Not quite correct. If you're concerned that someone might mutate the original map, you can make a defensive copy of it. `map - Collections.unmodifiableMap(new HashMap(map));` Of course, this still leaves the question of whether any of the objects in the map are themselves mutable. – David Conrad Jun 11 '13 at 19:49
7

It sounds like you would do very well with Guava's ImmutableMap. Which allows use of the Builder pattern to assemble and "freeze".

Louis Wasserman
  • 191,574
  • 25
  • 345
  • 413
Deadron
  • 5,135
  • 1
  • 16
  • 27
3

Wrap it in a class and make it immutable. For example:

public class ImmutableMapWrapper {

    private Map<String, String> map = new HashMap<String, String>();

    public ImmutableMapWrapper() {
        for( something ) {
            this.map.put( something );
        }
    }
}
m0skit0
  • 25,268
  • 11
  • 79
  • 127
1

Create an immutable HashMap:

HashMap <MyKey, MyValue> unmodifiableMap = Collections.unmodifiableMap(modifiableMap); 

JavaDoc here.

Also, I think the Google data collections utils (Guava???) has an ImmutableMap type already.

CodeChimp
  • 8,016
  • 5
  • 41
  • 79