CollectionsX.java Source code

Java tutorial

Introduction

Here is the source code for CollectionsX.java

Source

/* CollectionsX.java
    
{{IS_NOTE
    
  Purpose:
  Description:
  History:
  2001/09/15 13:46:20, Create, Tom M. Yeh.
}}IS_NOTE
    
Copyright (C) 2001 Potix Corporation. All Rights Reserved.
    
{{IS_RIGHT
  This program is distributed under GPL Version 3.0 in the hope that
  it will be useful, but WITHOUT ANY WARRANTY.
}}IS_RIGHT
*/

import java.util.AbstractCollection;
import java.util.Collection;
import java.util.Collections;
import java.util.Set;
import java.util.Map;
import java.util.AbstractList;
import java.util.List;
import java.util.LinkedList;
import java.util.Iterator;
import java.util.ListIterator;
import java.util.Enumeration;
import java.util.NoSuchElementException;

/**
 * The collection related utilities.
 *
 * @author tomyeh
 * @see java.util.Collections
 */
public class CollectionsX {
    /** An enumeration on top of a collection or iterator.
     */
    public static final class CollectionEnumeration implements Enumeration {
        private final Iterator _iter;

        public CollectionEnumeration(Collection c) {
            this(c != null ? c.iterator() : null);
        }

        public CollectionEnumeration(Iterator iter) {
            _iter = iter;
        }

        public final boolean hasMoreElements() {
            return _iter != null && _iter.hasNext();
        }

        public final Object nextElement() {
            if (_iter != null)
                return _iter.next();
            throw new NoSuchElementException();
        }
    }

    /** An enumeration on top of an array.
     */
    public static final class ArrayEnumeration implements Enumeration {
        private final Object[] _ary;
        private int _cursor = 0;

        public ArrayEnumeration(Object[] ary) {
            _ary = ary;
        }

        public final boolean hasMoreElements() {
            return _ary != null && _cursor < _ary.length;
        }

        public final Object nextElement() {
            if (hasMoreElements())
                return _ary[_cursor++];
            throw new NoSuchElementException();
        }
    }

    /** An enumeration that enumerates one element.
     */
    public static final class OneEnumeration implements Enumeration {
        private boolean _nomore;
        private final Object _one;

        public OneEnumeration(Object one) {
            _one = one;
        }

        public final boolean hasMoreElements() {
            return !_nomore;
        }

        public final Object nextElement() {
            if (_nomore)
                throw new NoSuchElementException();
            _nomore = true;
            return _one;
        }
    }

    /** An readonly collection on top of an array.
     */
    public static final class ArrayCollection extends AbstractCollection {
        private final Object[] _ary;

        public ArrayCollection(Object[] ary) {
            _ary = ary;
        }

        public final int size() {
            return _ary != null ? _ary.length : 0;
        }

        public Iterator iterator() {
            return new ArrayIterator(_ary);
        }
    }

    /** An readonly list on top of an array.
     */
    public static final class ArrayList extends AbstractList {
        private final Object[] _ary;

        public ArrayList(Object[] ary) {
            _ary = ary;
        }

        public final int size() {
            return _ary != null ? _ary.length : 0;
        }

        public final Object get(int index) {
            return _ary[index];
        }
    }

    /** An iterator on top of an array.
     */
    public static class ArrayIterator implements Iterator {
        /*package*/ final Object[] _ary;
        /*package*/ int _cursor = 0, _last = -1;

        /** @param ary an array or null. */
        public ArrayIterator(Object[] ary) {
            _ary = ary;
        }

        public final boolean hasNext() {
            return _ary != null && _cursor < _ary.length;
        }

        public final Object next() {
            if (hasNext())
                return _ary[_last = _cursor++];
            throw new NoSuchElementException("cursor=" + _cursor);
        }

        public final void remove() {
            throw new UnsupportedOperationException();
        }
    }

    public static class ArrayListIterator extends ArrayIterator implements ListIterator {
        /** @param ary an array or null. */
        public ArrayListIterator(Object[] ary) {
            super(ary);
        }

        /** @param ary an array or null. */
        public ArrayListIterator(Object[] ary, int index) {
            super(ary);
            _cursor = index;
            final int len = _ary != null ? _ary.length : 0;
            if (_cursor < 0 || _cursor > len)
                throw new IndexOutOfBoundsException("index=" + index + " but len=" + len);
        }

        public final boolean hasPrevious() {
            return _ary != null && _cursor > 0;
        }

        public final Object previous() {
            if (hasPrevious())
                return _ary[_last = --_cursor];
            throw new NoSuchElementException("cursor=" + _cursor);
        }

        public final int nextIndex() {
            return _cursor;
        }

        public final int previousIndex() {
            return _cursor - 1;
        }

        public final void set(Object o) {
            if (_last < 0)
                throw new IllegalStateException("neither next nor previous have been called");
            _ary[_last] = o;
        }

        public final void add(Object o) {
            throw new UnsupportedOperationException();
        }
    }

    /** A collection that contains only one element.
     */
    public static final class OneCollection extends AbstractCollection {
        private final Object _one;

        public OneCollection(Object one) {
            _one = one;
        }

        public final int size() {
            return 1;
        }

        public Iterator iterator() {
            return new OneIterator(_one);
        }
    }

    /** An iterator that iterates one element.
     */
    public static final class OneIterator implements Iterator {
        private boolean _nomore;
        private final Object _one;

        public OneIterator(Object one) {
            _one = one;
        }

        public final boolean hasNext() {
            return !_nomore;
        }

        public final Object next() {
            if (_nomore)
                throw new NoSuchElementException();
            _nomore = true;
            return _one;
        }

        public final void remove() {
            throw new UnsupportedOperationException();
        }
    }

    /** An iterator that iterates thru an Enumeration.
     */
    public static final class EnumerationIterator implements Iterator {
        private final Enumeration _enm;

        /**
         * @param enm the enumeration. If null, it means empty.
         */
        public EnumerationIterator(Enumeration enm) {
            _enm = enm;
        }

        public final boolean hasNext() {
            return _enm != null && _enm.hasMoreElements();
        }

        public final Object next() {
            if (_enm == null)
                throw new NoSuchElementException();
            return _enm.nextElement();
        }

        public final void remove() {
            throw new UnsupportedOperationException();
        }
    };

    /** Empty iterator.
     */
    public static final Iterator EMPTY_ITERATOR = new Iterator() {
        public final boolean hasNext() {
            return false;
        }

        public final Object next() {
            throw new NoSuchElementException();
        }

        public final void remove() {
            throw new IllegalStateException();
        }
    };
    /** Empty enumeration.
     */
    public static final Enumeration EMPTY_ENUMERATION = new Enumeration() {
        public final boolean hasMoreElements() {
            return false;
        }

        public final Object nextElement() {
            throw new NoSuchElementException();
        }
    };

    /**
     * Returns the specified range of the specified collection into a new array.
       * The initial index of the range (<tt>from</tt>) must lie between zero
       * and <tt>col.size</tt>, inclusive. 
       * The final index of the range (<tt>to</tt>), which must be greater than or
       * equal to <tt>from</tt>.
       * <p>The returned array will be "safe" in that no references to it are
       * maintained by this list.  (In other words, this method must allocate
       * a new array).  The caller is thus free to modify the returned array.
       *
       * <p>This method acts as bridge between array-based and collection-based
       * APIs.
     * @param col the collection to be copied.
     * @param from the initial index of the range to be copied, inclusive.
       * @param to the final index of the range to be copied, exclusive.
       * @since 3.0.6
     */
    public static final Object[] toArray(Collection col, int from, int to) {
        int newLength = to - from;
        if (newLength < 0)
            throw new IllegalArgumentException(from + " > " + to);
        Object[] result = new Object[newLength];
        int i = 0, j = 0;
        for (Iterator it = col.iterator(); it.hasNext() && i < result.length;) {
            if (j++ < from) {
                it.next();
                continue;
            }
            result[i++] = it.next();
        }
        return result;
    }

    /** Adds all elements returned by the iterator to a collection.
     * @param iter the iterator; null is OK
     * @return the number element being added
     */
    public static final int addAll(Collection col, Iterator iter) {
        int cnt = 0;
        if (iter != null)
            for (; iter.hasNext(); ++cnt)
                col.add(iter.next());
        return cnt;
    }

    /** Adds all elements returned by the enumerator to a collection.
     * @param enm the enumeration; null is OK
     * @return the number element being added
     */
    public static final int addAll(Collection col, Enumeration enm) {
        int cnt = 0;
        if (enm != null)
            for (; enm.hasMoreElements(); ++cnt)
                col.add(enm.nextElement());
        return cnt;
    }

    /** Adds all elements of an array to a collection.
     * @param ary the array; null is OK
     * @return the number element being added
     */
    public static final int addAll(Collection col, Object[] ary) {
        int cnt = 0;
        if (ary != null)
            for (; cnt < ary.length; ++cnt)
                col.add(ary[cnt]);
        return cnt;
    }

    /** Tests whether two sets has any intersection.
     */
    public static final boolean isIntersected(Set a, Set b) {
        final int sza = a != null ? a.size() : 0;
        final int szb = b != null ? b.size() : 0;
        if (sza == 0 || szb == 0)
            return false;

        final Set large, small;
        if (sza > szb) {
            large = a;
            small = b;
        } else {
            large = b;
            small = a;
        }
        for (final Iterator it = small.iterator(); it.hasNext();)
            if (large.contains(it.next()))
                return true;
        return false;
    }

    /**
     * Based on the given collection type of Object, return an iterator. The
     * Collection type of object can be Collection, Map (return the entry), or
     * Array.
     */
    public static final Iterator iterator(Object obj) {
        if (obj instanceof Object[]) {
            return new ArrayIterator((Object[]) obj);
        } else if (obj instanceof Collection) {
            return ((Collection) obj).iterator();
        } else if (obj instanceof Map) {
            return ((Map) obj).entrySet().iterator();
        }
        throw new IllegalArgumentException("obj must be a Collection, a Map, or an Object array. obj: " + obj);
    }
}