package com.googlecode.totallylazy; import com.googlecode.totallylazy.comparators.Comparators; import com.googlecode.totallylazy.iterators.StatefulIterator; import com.googlecode.totallylazy.time.Seconds; import java.util.Date; import java.util.List; import static com.googlecode.totallylazy.Pair.pair; import static com.googlecode.totallylazy.Sequences.sequence; import static com.googlecode.totallylazy.Sequences.sort; import static com.googlecode.totallylazy.time.Dates.stripTime; import static java.lang.Math.abs; public class Randoms { private static java.util.Random random = new java.util.Random(); public static Sequence<Integer> integers() { return Sequences.forwardOnly(new StatefulIterator<Integer>() { @Override protected Integer getNext() throws Exception { return random.nextInt(); } }); } public static Sequence<Long> longs() { return Sequences.forwardOnly(new StatefulIterator<Long>() { @Override protected Long getNext() throws Exception { return random.nextLong(); } }); } public static Sequence<Double> doubles() { return Sequences.forwardOnly(new StatefulIterator<Double>() { @Override protected Double getNext() throws Exception { return random.nextDouble(); } }); } public static Sequence<Boolean> booleans() { return Sequences.forwardOnly(new StatefulIterator<Boolean>() { @Override protected Boolean getNext() throws Exception { return random.nextBoolean(); } }); } public static Sequence<Date> dates() { return Sequences.forwardOnly(new StatefulIterator<Date>() { @Override protected Date getNext() throws Exception { return stripTime(new Date(random.nextLong())); } }); } @SafeVarargs public static <T> Sequence<T> values(final T... values) { return Sequences.forwardOnly(new StatefulIterator<T>() { @Override protected T getNext() throws Exception { return values[random.nextInt(values.length)]; } }); } @SafeVarargs public static <T> Sequence<T> takeFromValues(final T... values) { return takeFromValues(sequence(values)); } public static <T> Sequence<T> takeFromValues(final Iterable<T> values) { final List<T> list = sequence(values).toList(); return Sequences.forwardOnly(new StatefulIterator<T>() { @Override protected T getNext() throws Exception { if (list.isEmpty()) return finished(); int index = random.nextInt(list.size()); return list.remove(index); } }); } public static Sequence<Integer> between(final int start, final int end) { final Pair<Integer, Integer> bounds = bounds(start, end); return Sequences.forwardOnly(new StatefulIterator<Integer>() { @Override protected Integer getNext() throws Exception { int range = bounds.second() - bounds.first() + 1; return random.nextInt(Math.max(1, abs(range))) + bounds.first(); } }); } public static Sequence<Double> between(final Double start, final Double end) { final Pair<Double, Double> bounds = bounds(start, end); return Sequences.forwardOnly(new StatefulIterator<Double>() { @Override protected Double getNext() throws Exception { return bounds.first() + random.nextDouble() * (bounds.second() - bounds.first()); } }); } public static Sequence<Date> between(final Date start, final Date end) { final Pair<Date, Date> bounds = bounds(start, end); return Sequences.forwardOnly(new StatefulIterator<Date>() { @Override protected Date getNext() throws Exception { return Seconds.add(bounds.first(), between(0, daysBetween(bounds.first(), bounds.second())).head()); } private int daysBetween(Date start, Date end) { return (int) abs((end.getTime() - start.getTime()) / 1000); } }); } public static Sequence<Date> after(final Date date) { return between(date, new Date(Long.MAX_VALUE)); } private static <T extends Comparable<? super T>> Pair<T, T> bounds(T start, T end) { final Sequence<T> sorted = sort(sequence(start, end), Comparators.<T>ascending()); return pair(sorted.first(), sorted.second()); } }