package org.limewire.collection; import java.util.Iterator; import java.util.NoSuchElementException; /** * Generates all the integers from 0 to a certain limit in a * random fashion where each number is generated only once per cycle. * <p> * <code>RandomSequence</code> also implements the <code>Iterable</code> * interface that iterates over a single cycle. * <p> * For more information regarding the logic, see <a href= * "http://en.wikipedia.org/wiki/Linear_congruential_generator">Linear * congruential generator</a>. * <p> * Thanks to Cyclonus for the pow2 hint. <pre> for(Integer o : new RandomSequence(10)) System.out.println(o); Random Output: 4 7 2 5 0 3 1 8 6 9 </pre> */ public class RandomSequence implements Iterable<Integer> { private final int end; private final long pow2, a; private long seed; public RandomSequence(int end) { this.end = end; // empty or single-element sequence if (end <= 1) { pow2 = 0; a = 0; return; } long pow = 1; while (pow < end) pow <<= 1; pow2 = pow - 1; a = (((int)(Math.random() * (pow2 >> 2))) << 2) + 1; seed = (int)(Math.random() * end); } public int nextInt() { if (end < 1) throw new NoSuchElementException(); if (end == 1) return 0; do { seed = (a * seed + 3 ) & pow2; } while (seed >= end || seed < 0); return (int)seed; } public Iterator<Integer> iterator() { return new RandomIterator(); } private class RandomIterator extends UnmodifiableIterator<Integer> { private int given; public boolean hasNext() { return given < end; } public Integer next() { if (!hasNext()) throw new NoSuchElementException(); given++; return nextInt(); } } }