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
.
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
.
Something like this:
This depends on the pool element class implementing the
equals
andhashCode
to provide "equality by value" and to obey to the API contracts for those methods. ButBigDecimal
certainly does.UPDATE - for an explanation of why we need a
WeakHashMap<T, WeakReference<T>>
rather than aWeakHashMap<T, T>
, see the javadocs. The short version is that the key weak-links in the latter won't be broken by the GC because the corresponding entry references are making the values strongly reachable.For an example take a look at
Interner
from Guava. It does not require anInternable
interface, it just relies onequals
andhashCode
.Just a quick caveat:
It has not been explicitly mentioned above, but it should be obvious that the objects being interned must be of an immutable type.
On a second note: You don't need to use another weak reference to the object as the value in the map, a reference to a static would suffice if you just rely on the map's keyset for the data. For example, declare:
And insert pairs as:
Which is a minor saving of a WeakReference instance (if you can't reuse the one used for the key).
...or create a WeakSet class, as @PeterVerhas has done with his WeakPool.
Shouldnt
"WeakReference ref = pool.get(object);"
instead be
WeakReference ref = pool.intern(object);
??
This more sounds like that you're looking for flyweight pattern.
Click the link, it contains a Java example.
I would separate the solution into two classes to have cleaner code and also this way getting rid of loop:
and the interning class using the weak pool is very simple: