//
// $Id: CollectionUtil.java,v 1.7 2004/06/12 23:17:02 ray Exp $
//
// samskivert library - useful routines for java programs
// Copyright (C) 2001 Michael Bayne
// 
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

package com.samskivert.util;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;

/**
 * A collection of collection-related utility functions.
 */
public class CollectionUtil
{
    /**
     * Adds all items returned by the enumeration to the supplied
     * collection and returns the supplied collection.
     */
    public static <E, T extends Collection<E>> T addAll (
            T col, Enumeration<E> enm)
    {
        while (enm.hasMoreElements()) {
            col.add(enm.nextElement());
        }
        return col;
    }

    /**
     * Adds all items returned by the iterator to the supplied collection
     * and returns the supplied collection.
     */
    public static <E, T extends Collection<E>> T addAll (
            T col, Iterator<E> iter)
    {
        while (iter.hasNext()) {
            col.add(iter.next());
        }
        return col;
    }

    /**
     * Adds all items in the given object array to the supplied
     * collection and returns the supplied collection.
     */
    public static <E, T extends Collection<E>> T addAll (T col, E[] values)
    {
        for (int ii = 0; ii < values.length; ii++) {
            col.add(values[ii]);
        }
        return col;
    }

    /**
     * Returns a list containing a random selection of elements from the
     * specified collection. The total number of elements selected will be
     * equal to <code>count</code>, each element in the source collection
     * will be selected with equal probability and no element will be
     * included more than once. The elements in the random subset will
     * always be included in the order they are returned from the source
     * collection's iterator.
     *
     * <p> Algorithm courtesy of William R. Mahoney, published in
     * <cite>Dr. Dobbs Journal, February 2002</cite>.
     *
     * @exception IllegalArgumentException thrown if the size of the
     * collection is smaller than the number of elements requested for the
     * random subset.
     */
    public static <T> List<T> selectRandomSubset (Collection<T> col, int count)
    {
        int csize = col.size();
        if (csize < count) {
            String errmsg = "Cannot select " + count + " elements " +
                "from a collection of only " + csize + " elements.";
            throw new IllegalArgumentException(errmsg);
        }

        ArrayList<T> subset = new ArrayList<T>();
        Iterator<T> iter = col.iterator();
        int s = 0;

        for (int k = 0; iter.hasNext(); k++) {
            T elem = iter.next();

            // the probability that an element is select for inclusion in
            // our random subset is proportional to the number of elements
            // remaining to be checked for inclusion divided by the number
            // of elements remaining to be included
            float limit = ((float)(count - s)) / ((float)(csize - k));

            // include the record if our random value is below the limit
            if (Math.random() < limit) {
                subset.add(elem);

                // stop looking if we've reached our target size
                if (++s == count) {
                    break;
                }
            }
        }

        return subset;
    }


    /**
     * If a collection contains only <code>Integer</code> objects, it can be
     * passed to this function and converted into an int array.
     *
     * @param col the collection to be converted.
     *
     * @return an int array containing the contents of the collection (in the
     * order returned by the collection's iterator). The size of the array will
     * be equal to the size of the collection.
     */
    public static int[] toIntArray (Collection<Integer> col)
    {
        Iterator<Integer> iter = col.iterator();
        int[] array = new int[col.size()];
        for (int i = 0; iter.hasNext(); i++) {
            array[i] = iter.next().intValue();
        }
        return array;
    }
}

@@ -1224,39 +1224,32 @@
  to the supplied
-%0A     *
  collection and 
@@ -1235,32 +1235,39 @@
 plied collection
+%0A     *
  and returns the
@@ -1593,35 +1593,35 @@
 d collection
+ and
 %0A     *
- and
  returns the
@@ -1926,23 +1926,16 @@
 supplied
-%0A     *
  collect
@@ -1937,24 +1937,31 @@
 llection and
+%0A     *
  returns the
@@ -1973,32 +1973,106 @@
 lied collection.
+ If the supplied array is null, nothing%0A     * is added to the collection.
 %0A     */%0A    pub
@@ -2138,32 +2138,66 @@
 %5D values)%0A    %7B%0A
+        if (values != null) %7B%0A    
         for (int
@@ -2237,32 +2237,36 @@
 ) %7B%0A            
+    
 col.add(values%5Bi
@@ -2270,16 +2270,30 @@
 s%5Bii%5D);%0A
+            %7D%0A
         
@@ -2554,20 +2554,20 @@
 tion
+ will
 %0A     *
- will
  be 
@@ -2620,23 +2620,16 @@
  will be
-%0A     *
  include
@@ -2634,16 +2634,23 @@
 ded more
+%0A     *
  than on
@@ -2691,23 +2691,16 @@
 set will
-%0A     *
  always 
@@ -2709,24 +2709,31 @@
  included in
+%0A     *
  the order t
@@ -2764,23 +2764,16 @@
 e source
-%0A     *
  collect
@@ -2990,23 +2990,16 @@
 e of the
-%0A     *
  collect
@@ -3001,16 +3001,23 @@
 llection
+%0A     *
  is smal
@@ -3065,23 +3065,16 @@
  for the
-%0A     *
  random 
@@ -3710,16 +3710,20 @@
 usion in
+ our
 %0A       
@@ -3729,20 +3729,16 @@
       //
- our
  random 
@@ -3860,16 +3860,19 @@
 e number
+ of
 %0A       
@@ -3878,19 +3878,16 @@
       //
- of
  element

Allow passing a null array to CollectionUtil.addAll() which behaves like an empty array.