import java.util.*;
interface ItemChooser<T>
{
T getNext();
T getSentinel();
int size();
void reset();
}
abstract class AbstractItemChooser<T> implements ItemChooser<T>
{
private T sentinel;
private T[] items;
private List<T> available;
protected AbstractItemChooser(T[] items, T sentinelValue)
{
this.items = items;
this.sentinel = sentinel;
available = new ArrayList<T>(items.length);
reset();
}
public T getNext()
{
return available.size() > 0 ? available.remove(getIndexOfNext()) : sentinel;
}
public T getSentinel()
{
return sentinel;
}
public int size()
{
return available.size();
}
public void reset()
{
available.clear();
for (int i = 0; i < items.length; i++)
{
available.add(items[i]);
}
}
protected abstract int getIndexOfNext();
}
class RandomItemChooser<T> extends AbstractItemChooser<T>
{
public RandomItemChooser(T[] items, T sentinel)
{
super(items, sentinel);
}
protected int getIndexOfNext()
{
return (int)(Math.random() * size());
}
}
class RandomStringChooser extends RandomItemChooser<String>
{
public RandomStringChooser(String[] strings)
{
super(strings, "NONE");
}
}
public class Items {
public static <T> void process(ItemChooser<T> chooser)
{
while (chooser.size() > 0)
{
System.out.print(chooser.getNext() + " ");
}
System.out.println();
}
public static void main(String args[]) {
ItemChooser<String> randomChooser, sequentialChooser, reverseChooser;
randomChooser = new RandomStringChooser(args);
process(randomChooser);
//process(sequentialChooser);
//process(reverseChooser);
}
}