Java程序  |  186行  |  3.77 KB

package annotations.util.coll;

import java.util.*;

/*>>>
import org.checkerframework.checker.nullness.qual.*;
*/

/**
 * A simple implementation of {@link KeyedSet} backed by an insertion-order
 * {@link java.util.LinkedHashMap} and its
 * {@link java.util.LinkedHashMap#values() value collection}.
 */
public class LinkedHashKeyedSet<K, V> extends AbstractSet<V> implements KeyedSet<K, V> {
    private final Keyer<? extends K, ? super V> keyer;

    private final Map<K, V> theMap = new LinkedHashMap<K, V>();

    final Collection<V> theValues = theMap.values();

    /**
     * Constructs a {@link LinkedHashKeyedSet} that uses the given
     * {@link Keyer} to obtain keys for elements.
     */
    public LinkedHashKeyedSet(Keyer<? extends K, ? super V> keyer) {
        this.keyer = keyer;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public int size() {
        return theValues.size();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean contains(Object o) {
        return theValues.contains(o);
    }

    private class KeyedSetIterator implements Iterator<V> {
        private final Iterator<V> itr = theValues.iterator();

        @Override
        public boolean hasNext() {
            return itr.hasNext();
        }

        @Override
        public V next() {
            return itr.next();
        }

        @Override
        public void remove() {
            itr.remove();
        }

        KeyedSetIterator() {
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Iterator<V> iterator() {
        return new KeyedSetIterator();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Object[] toArray() {
        return theValues.toArray();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public <T> T[] toArray(T[] a) {
        return theValues.toArray(a);
    }

    private boolean checkAdd(int behavior, V old) {
        switch (behavior) {
        case REPLACE:
            remove(old);
            return true;
        case IGNORE:
            return false;
        case THROW_EXCEPTION:
            throw new IllegalStateException();
        default:
            throw new IllegalArgumentException();
        }
    }

    private static boolean eq(Object x, Object y) {
        return x == y || (x != null && x.equals(y));
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public V add(V o, int conflictBehavior, int equalBehavior) {
        K key = keyer.getKeyFor(o);
        V old = theMap.get(key);
        if (old == null
                || (eq(o, old) ? checkAdd(equalBehavior, old) : checkAdd(
                        conflictBehavior, old)))
            theMap.put(key, o);
        return old;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean add(V o) {
        return add(o, THROW_EXCEPTION, IGNORE) == null;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean remove(Object o) {
        return theValues.remove(o);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean addAll(Collection<? extends V> c) {
        boolean changed = false;
        for (V o : c) {
            changed |= add(o);
        }
        return changed;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void clear() {
        theValues.clear();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Keyer<? extends K, ? super V> getKeyer() {
        return keyer;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public V replace(V v) {
        return theMap.put(keyer.getKeyFor(v), v);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public V lookup(K k) {
        return theMap.get(k);
    }

    // Use inherited equals and hashCode algorithms because
    // those of HashMap.Values are broken!
}