DiscreteRandomProducer extends RandomProducerWithGenerator { @Override public Double get() { double p = generator().nextDouble(); for (int i = 0; i < probs.length; i++) { if (probs[i] > p) return (double)ids[i]; } return (double)ids[probs.length - 1]; } DiscreteRandomProducer(double... probs);  DiscreteRandomProducer(long seed, double... probs); static DiscreteRandomProducer uniform(int numOfValues); static DiscreteRandomProducer uniform(int numOfValues, long seed); static double[] randomDistribution(int numOfValues); static double[] randomDistribution(int numOfValues, long seed); @Override Double get(); int getInt(); int size();  }
@Test public void testGet() { double[] probs = new double[] {0.1, 0.2, 0.3, 0.4}; DiscreteRandomProducer producer = new DiscreteRandomProducer(0L, probs); Map<Integer, Double> counters = new HashMap<>(); IntStream.range(0, probs.length).forEach(i -> counters.put(i, 0.0)); final int N = 500000; Stream.generate(producer::getInt).limit(N).forEach(i -> counters.put(i, counters.get(i) + 1)); IntStream.range(0, probs.length).forEach(i -> counters.put(i, counters.get(i) / N)); for (int i = 0; i < probs.length; i++) assertEquals(probs[i], counters.get(i), 0.01); assertEquals(probs.length, producer.size()); }
@Test public void testSeedConsidering() { DiscreteRandomProducer producer1 = new DiscreteRandomProducer(0L, 0.1, 0.2, 0.3, 0.4); DiscreteRandomProducer producer2 = new DiscreteRandomProducer(0L, 0.1, 0.2, 0.3, 0.4); assertEquals(producer1.get(), producer2.get(), 0.0001); }