/*
* Copyright 2007 (C) TJDO.
* All rights reserved.
*
* This software is distributed under the terms of the TJDO License version 1.0.
* See the terms of the TJDO License in the documentation provided with this software.
*
* $Id: InternPool.java,v 1.1 2007/11/30 19:42:26 jackknifebarber Exp $
*/
import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
import java.util.AbstractCollection;
import java.util.Collections;
import java.util.Iterator;
import java.util.Map;
import java.util.WeakHashMap;
/**
* Implements a pool of <dfn>internalized</dfn> objects.
* Used to implement pools that behave like the one used by String.intern().
* <p>
* This implementation is synchronized.
* It is a generic collection that is unmodifiable with the exception of the
* {@link #intern} method.
*
* @author <a href="mailto:jackknifebarber@users.sourceforge.net">Mike Martin</a>
* @version $Revision: 1.1 $
*/
public class InternPool extends AbstractCollection
{
private final Map pool = new WeakHashMap();
/**
* Returns a canonical representation for the specified object.
* <p>
* This method behaves much like <code>String.intern()</code>.
* A pool of objects, initially empty, is maintained privately.
* <p>
* If the pool already contains an object equal to the specified object as
* determined by the <code>equals(Object)</code> method, then the object
* from the pool is returned.
* Otherwise, the specified object is added to the pool and a reference to
* the specified object is returned.
* <p>
* It follows that for any two objects <code>o1</code> and <code>o2</code>,
* <code>intern(o1) == intern(o2)</code> is <code>true</code>
* if and only if <code>o1.equals(o2)</code> is <code>true</code>.
*
* @param candidate
* the object to internalize
*
* @return
* an object that is equivalent to the specified object, but is
* guaranteed to be from a pool of unique objects.
*/
public synchronized Object intern(Object candidate)
{
Reference ref = (Reference)pool.get(candidate);
Object pooled = ref == null ? null : ref.get();
if (pooled == null)
{
pooled = candidate;
pool.put(pooled, new WeakReference(pooled));
}
return pooled;
}
public synchronized boolean contains(Object o)
{
return pool.containsKey(o);
}
public synchronized Iterator iterator()
{
return Collections.unmodifiableSet(pool.keySet()).iterator();
}
public synchronized int size()
{
return pool.size();
}
}
|