package org.magenta.random; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Random; import com.google.common.base.Preconditions; import com.google.common.collect.Lists; /** * Helper class for random selection of objects from a list. * * @author ngagnon * * @param <E> the type of data produced by this class */ public class RandomList<E> { private final List<E> values; private final RandomInteger integers; private final Random random; /** * Default constructor. * * @param random the random to use (for shuffling) * @param integers the {@code RandomInteger} to use (for picks) * @param values the list from which to pick values */ public RandomList(Random random, RandomInteger integers, List<E> values) { this.integers = integers; this.values = values; this.random = random; } /** * Pick any value within this instance own values. * * @return a randomly picked value */ public E any() { Preconditions.checkState(!values.isEmpty(), "No items in the list to select, the list is empty"); return values.get(integers.anyPositive(values.size())); } /** * Pick any value within this instance own values hile avoiding the one defined within {@code thoseOnes}. * @param thoseOnes the values to avoid * @return a randomly picked value */ @SafeVarargs public final E anyBut(E... thoseOnes) { List<E> l = Lists.newArrayList(values); l.removeAll(Arrays.asList(thoseOnes)); return l.get(integers.anyPositive(l.size())); } /** * Pick some values within this instance own values. * * @return a of random size list of values randomly picked from this instance own values. */ public List<E> some() { Preconditions.checkState(!values.isEmpty(), "No items in the list to select, the list is empty"); int numberOfItemsToPick = integers.anyPositive(values.size()); return shuffle().list().subList(0, numberOfItemsToPick); } /** * Pick some values within this instance own values while avoiding the one defined within {@code thoseOnes}. * * @param thoseOnes the values to avoid * @return a random size list of values randomly picked from this instance own values. */ @SafeVarargs public final List<E> someBut(E... thoseOnes) { Preconditions.checkState(!values.isEmpty(), "No items in the list to select, the list is empty"); int numberOfItemsToPick = integers.anyPositive(values.size()); List<E> l = Lists.newArrayList(values); l.removeAll(Arrays.asList(thoseOnes)); Collections.shuffle(l, random); return l.subList(0, numberOfItemsToPick); } /** * Pick some values within this instance own values. * @param numberOfItemsToPick the number of items to pick * @return a list of values randomly picked from this instance own values. */ public List<E> some(int numberOfItemsToPick) { Preconditions.checkState(!values.isEmpty(), "No items in the list to select, the list is empty"); Preconditions.checkState(values.size() > numberOfItemsToPick, "The number Of items to pick is greater than the number of items in the list"); return shuffle().list().subList(0, numberOfItemsToPick); } /** * Shuffle the values of this instance. * * @return this instance */ public RandomList<E> shuffle() { Collections.shuffle(values, random); return this; } /** * Return the values contained in this {@code RandomList}. * * @return the values */ public List<E> list() { return this.values; } }