FuriousGeorge
FuriousGeorge

Reputation: 4681

Create a hashmap of immutable generic objects

I don't think that there is a way that is efficient (if at all) of doing this, but I figured I'd ask in case someone else knows otherwise. I'm looking to create my own Cache/lookup table. To make it as useful as possible, I'd like it to be able to store generic objects. The problem with this approach is that even though you can make a Collections.unmodifiableMap, immutableMap, etc, these implementations only prevent you from changing the Map itself. They don't prevent you from getting the value from the map and modifying its underlying values. Essentially what I'd need is for something to the effect of HashMap<K, ? extends Immutable>, but to my knowledge nothing like this exists.

I had originally thought that I could just return a copy of the values in the cache in the get method, but since Java's Cloneable interface is jacked up, you cannot simple call

public V getItem(K key){
    return (V) map.get(k).clone();
}

Upvotes: 6

Views: 906

Answers (4)

newacct
newacct

Reputation: 122449

There is no formal concept of "mutability" or "immutability" in the language. The compiler cannot tell whether a type is "mutable" or "immutable". To determine whether something is immutable, we humans have to examine every field and method of the class, and reason through the behavior of the methods to discover that none of them will alter the state of the object, then we call it "immutable". But there is no difference from the perspective of the language.

Upvotes: 1

Bohemian
Bohemian

Reputation: 425083

Your thinking is good, and you're right that there's no built-in way of handling immutability.

However, you could try this:

interface Copyable<T> {
    T getCopy();
}

Then override the get() method to return copies instead of the value itself;

class CopyMap<K, V extends Copyable<V>> extends HashMap<K, V> {
    @Override
    public V get(Object key) {
        return super.get(key).getCopy();
    }
}

Then it's up to the implementation to return a copy of itself, rather than this (unless the class itself is immutable). Although you can't enforce that in code, you would be within your rights to publicly humiliate the programmer that doesn't conform.

Upvotes: 5

Andrey Chaschev
Andrey Chaschev

Reputation: 16496

There are other options for object cloning in Java: Making a copy of an object Dynamically?

Be aware though that deep cloning any object might be dangerous. The objects stored in this map must be i.e. isolated from each other, to make sure that whole object graph won't be copied when returning a single entry.

Upvotes: 1

Amir Afghani
Amir Afghani

Reputation: 38541

I'm looking to create my own Cache/lookup table.

Why not use Guava's cache?

The problem with this approach is that even though you can make a Collections.unmodifiableMap, immutableMap, etc, these implementations only prevent you from changing the Map itself. They don't prevent you from getting the value from the map and modifying its underlying values.

This is not something any collection can enforce for you. You need to make the classes themselves immutable. There is a hacky approach using Reflection (which can also be used to make a class mutable!), but really, you should avoid this and simply create classes that are immutable.

Upvotes: 2

Related Questions