Java Collection Random Element selectRandomSubset(Collection col, int count)

Here you can find the source of selectRandomSubset(Collection col, int count)

Description

Returns a list containing a random selection of elements from the specified collection.

License

Open Source License

Declaration

public static <T> List<T> selectRandomSubset(Collection<T> col, int count) 

Method Source Code


//package com.java2s;

import java.util.ArrayList;
import java.util.Collection;

import java.util.Iterator;
import java.util.List;

public class Main {
    /**/* www.ja v  a  2  s. c  om*/
     * 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>(count);
        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;
    }
}

Related

  1. randomIterable(Collection col)
  2. rndSubset(final Collection c, final double ratio)
  3. sampleWithReplacement(Collection c, int n)
  4. selectRandom(Collection set)
  5. selectRandom(Collection col)
  6. uniformSample(Collection set)