Class Java

/*
 * 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 internalized objects.
 * Used to implement pools that behave like the one used by String.intern().
 * 


 * This implementation is synchronized.
 * It is a generic collection that is unmodifiable with the exception of the
 * {@link #intern} method.
 *
 * @author Mike Martin
 * @version $Revision: 1.1 $
 */
public class InternPool extends AbstractCollection
{
    private final Map pool = new WeakHashMap();
    /**
     * Returns a canonical representation for the specified object.
     * 


     * This method behaves much like String.intern().
     * A pool of objects, initially empty, is maintained privately.
     * 


     * If the pool already contains an object equal to the specified object as
     * determined by the equals(Object) 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.
     * 


     * It follows that for any two objects o1 and o2,
     * intern(o1) == intern(o2) is true
     * if and only if o1.equals(o2) is true.
     *
     * @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();
    }
}