views:

78

answers:

3

How would I write a generic InternPool<T> in Java? Does it need a Internable interface?

String in Java has interning capabilities; I want to intern classes like BigDecimal and Account.

+2  A: 

This more sounds like that you're looking for flyweight pattern.

Flyweight is a software design pattern. A flyweight is an object that minimizes memory use by sharing as much data as possible with other similar objects

Click the link, it contains a Java example.

BalusC
+1. I think these are both the same pattern (or maybe a Flyweight is just one application of an Interner) but I prefer "Flyweight" because it is easier to google
finnw
A: 

Something like this:

public class InternPool<T> {

    private WeakHashMap<T, WeakReference<T>> pool = 
        new WeakHashMap<T, WeakReference<T>>();

    public synchronized T intern(T object) {
        T res = null;
        // (The loop is needed to deal with race
        // conditions where the GC runs while we are
        // accessing the 'pool' map or the 'ref' object.)
        do {
            WeakReference<T> ref = pool.get(object);
            if (ref == null) {
                ref = new WeakReference<T>(object);
                pool.put(object, ref);
                res = object;
            } else {
                res = ref.get();
            }
        } while (res == null);
        return res;
    }
}

This depends on the pool element class implementing the equals and hashCode to provide "equality by value" and to obey to the API contracts for those methods. But BigDecimal certainly does.

Stephen C
I assume you don't need to check if ref.get() is null.
Peter Lawrey
I thought not, but I've realized that there is a race condition with the GC. If the GC runs immediately after the call to `get`, the `ref` returned might be broken by the time we look at it. The whole lot needs to be in a loop. Updated.
Stephen C
A: 

For an example take a look at Interner from Guava. It does not require an Internable interface, it just relies on equals and hashCode.

finnw