Skip to content

Instantly share code, notes, and snippets.

@nathanosoares
Last active April 14, 2017 19:49
Show Gist options
  • Save nathanosoares/1b1c136608e78f7e2f642195fa3b29ba to your computer and use it in GitHub Desktop.
Save nathanosoares/1b1c136608e78f7e2f642195fa3b29ba to your computer and use it in GitHub Desktop.
Java RandomCollection class
import java.util.HashSet;
import java.util.NavigableMap;
import java.util.Random;
import java.util.Set;
import java.util.TreeMap;
import java.util.function.Predicate;
import java.util.stream.Collectors;
/**
*
* @author Nathan Soares <https://www.nathan.com.br>
* @version 1.0
* @since 2017-03-28
*/
public class RandomCollection<E> {
private final Set<RandomCollectionObject> set = new HashSet<>();
private final Random random;
public RandomCollection() {
this(new Random());
}
public RandomCollection(Random random) {
this.random = random;
}
public Set<RandomCollectionObject> getSet() {
return this.set;
}
public Random getRandom() {
return this.random;
}
public E put(Double weight, E value) {
if (weight <= 0) {
return null;
}
this.getSet().add(new RandomCollectionObject(value, weight));
return value;
}
public E raffle() {
return RandomCollection.this.raffle(this.getSet());
}
public E raffle(Predicate<? super RandomCollectionObject> predicate) {
Set<RandomCollectionObject> auxSet = this.getSet().stream()
.filter(predicate)
.collect(Collectors.toSet());
return RandomCollection.this.raffle(auxSet);
}
public E raffle(Set<RandomCollectionObject> set) {
NavigableMap<Double, RandomCollectionObject> auxMap = new TreeMap<>();
set.stream().forEach((rco) -> {
double auxWeight = auxMap.values().stream().mapToDouble(i -> i.getWeight()).sum();
auxWeight += rco.getWeight();
auxMap.put(auxWeight, rco);
});
double totalWeight = this.getRandom().nextDouble() * auxMap.values().stream().mapToDouble(i -> i.getWeight()).sum();
return auxMap.ceilingEntry(totalWeight).getValue().getObject();
}
public double totalWeight() {
return this.getSet().stream().mapToDouble(i -> i.getWeight()).sum();
}
public double totalWeight(Predicate<? super RandomCollectionObject> predicate) {
Set<RandomCollectionObject> auxSet = this.getSet().stream()
.filter(predicate)
.collect(Collectors.toSet());
return auxSet.stream().mapToDouble(i -> i.getWeight()).sum();
}
public int count() {
return this.getSet().size();
}
public class RandomCollectionObject {
private final E object;
private final Double weight;
public RandomCollectionObject(E object, Double weight) {
this.object = object;
this.weight = weight;
}
public Double getChance() {
return this.weight * 100 / RandomCollection.this.totalWeight();
}
public Double getChance(Double totalWeight) {
return this.weight * 100 / totalWeight;
}
public E getObject() {
return this.object;
}
public Double getWeight() {
return this.weight;
}
}
}
@nathanosoares
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment