### Question:
Weighted { public static <T extends Weighted<?>> List<T> sample(Iterable<T> things, int size, RandomGenerator random) { if (random == null) { random = RandomManager.getRandom(); } SortedMap<Double, T> sampled = Maps.newTreeMap(); for (T thing : things) { if (thing.weight() > 0) { double score = Math.log(random.nextDouble()) / thing.weight(); if (sampled.size() < size || score > sampled.firstKey()) { sampled.put(score, thing); } if (sampled.size() > size) { sampled.remove(sampled.firstKey()); } } } return Lists.newArrayList(sampled.values()); } Weighted(T thing);  Weighted(T thing, double weight); static Collection<Weighted<T>> create(Collection<T> things); static List<Weighted<T>> create(List<T> things); static List<T> sample(Iterable<T> things, int size, RandomGenerator random); T thing(); double weight(); @Override boolean equals(Object other); @Override int hashCode(); @Override String toString();  }### Answer:
@Test public void testBasic() throws Exception { Collection<Weighted<Integer>> things = Lists.newArrayList(); RandomGenerator rand = RandomManager.getRandom(); for (int i = 0; i < 50; i++) { things.add(new Weighted<Integer>(i, rand.nextDouble())); } List<Weighted<Integer>> s = Weighted.sample(things, 5, rand); assertEquals(ImmutableList.of(31, 46, 49, 23, 14), Lists.transform(s, new ThingFn<Integer>())); }
@Test public void testEmpty() throws Exception { RandomGenerator rand = RandomManager.getRandom(); assertEquals(0, Weighted.sample(ImmutableList.<Weighted<Long>>of(), 10, rand).size()); }
@Test public void testSmallerCollectionThanSize() throws Exception { RandomGenerator rand = RandomManager.getRandom(); Collection<Weighted<Integer>> things = Lists.newArrayList(); for (int i = 0; i < 5; i++) { things.add(new Weighted<Integer>(i, rand.nextDouble())); } List<Weighted<Integer>> s = Weighted.sample(things, 10, rand); assertEquals(ImmutableList.of(3, 4, 1, 0, 2), Lists.transform(s, new ThingFn<Integer>())); }