1

I need to make sure that a map content is final, it is once initialized by:

Map<K, V> map = new HashMap<K, V>(iAnotherMap);

Every calls to methods which modifiy the map content (as put, remove, replace ...) would end in errors.

But I still would be able to perform another:

map = new HashMap<K, V>(iAnotherMap);

Is there any way to achieve this ?

Thanks

EDIT: Trying the Collections.unmodifiableMap approach, but there's an issue:

The class I want to wrap is:

public class IndexedHashMap<K, T> implements Map<K, Pair< Integer, T >>, Serializable 

The following code returns an error:

IndexedHashMap< K, T > mCurrent = new IndexedHashMap< K, T >(); 
IndexedHashMap< K, T > mConstantCurrent = Collections.unmodifiableMap(mCurrent);' 

Type mismatch: cannot convert from Map> to IndexedHashMap

Any idea about this ?

Milan
  • 1,547
  • 1
  • 24
  • 47
  • 2
    Possible duplicate of [Returning an unmodifiable map](http://stackoverflow.com/questions/7066618/returning-an-unmodifiable-map) – OH GOD SPIDERS Mar 09 '17 at 14:34

3 Answers3

4

final will make your reference final but the map object will be still editable. You need to use existing unmodifiableMap wrapper from Collections

Map<K, V> map = Collections.unmodifiableMap(new HashMap<K, V>(iAnotherMap));

or to build your own implementation

m.antkowicz
  • 13,268
  • 18
  • 37
  • is it necessary to build a new HashMap ? `Map map = Collections.unmodifiableMap(iAnotherMap)` seems enough – AxelH Mar 09 '17 at 14:40
  • Becareful, unmodifiable map is just a view over a map, that still can be modified. See : https://stackoverflow.com/questions/8892350/immutable-vs-unmodifiable-collection – J.Mengelle Mar 09 '17 at 14:43
  • @AxelH, it *is* necessary to build a new map if there is a chance that the existing one will be modified, and that must not be reflected in the unmodifiable one. The suggested approach avoids that possibility. – John Bollinger Mar 09 '17 at 14:44
  • @JohnBollinger Ok, the `map` would use the same map reference but with an unmodifiable instance. So any change in `iAnotherMap` would be reflected in `map`. Thanks for that – AxelH Mar 09 '17 at 14:47
  • Thanks I am going to have a look at unmodifiableMap – Milan Mar 09 '17 at 16:29
  • It's actually great that an unmodifiable collection actually wrap a mutable map because, if needed, I can still implement my own implementation of necessary changes in my class, and only give the unmodifiable collection to consumers. Is there any way to prevent access to the actual map from a reference to the unmobidiableMap ? – Milan Mar 09 '17 at 17:08
  • Hi, I have an issue with `Collections.unmodifiableMap`, the class I want to wrap is: `public class IndexedHashMap implements Map>, Serializable` The following code returns an error: 'mCurrent = new IndexedHashMap< K, T >(); mConstantCurrent = Collections.unmodifiableMap(mCurrent);' Type mismatch: cannot convert from Map> to IndexedHashMap – Milan Mar 09 '17 at 19:43
1

You can use UnmodifiableMap. However, if your needs are too specific, you should extend the existing HashMap class and do whatever you want.

public class HashMap<K, V> extends java.util.HashMap<K, V> {

   @Override
    public V put(K key, V value) {
        // report error
        return null;
    }

    // similarly override other methods as you want

}
iavanish
  • 509
  • 3
  • 8
0

If you can use Guava, there is what you seek for :

com.google.common.collect.ImmutableMap

Else, you need to make your own implementation of HashMap to make it Immutable.

J.Mengelle
  • 341
  • 3
  • 11