diff --git a/src/main/java/com/samskivert/util/Randoms.java b/src/main/java/com/samskivert/util/Randoms.java
index 5cdbbff8..f5b4ef26 100644
--- a/src/main/java/com/samskivert/util/Randoms.java
+++ b/src/main/java/com/samskivert/util/Randoms.java
@@ -142,13 +142,41 @@ public class Randoms
return (float)_r.nextGaussian() * dev + mean;
}
+ /**
+ * Pick a random key from the specified mapping of weight values, or return
+ * ifEmpty if no mapping has a weight greater than 0.
+ *
+ * @throws IllegalArgumentException if any weight is less than 0.
+ */
+ public T pick (Map extends T, ? extends Number> weightMap, T ifEmpty)
+ {
+ T pick = ifEmpty;
+ double r = _r.nextDouble();
+ double total = 0.0;
+ for (Map.Entry extends T, ? extends Number> entry : weightMap.entrySet()) {
+ double weight = entry.getValue().doubleValue();
+ if (weight > 0.0) {
+ total += weight;
+ if ((r * total) < weight) {
+ pick = entry.getKey();
+ }
+ } else if (weight < 0.0) {
+ throw new IllegalArgumentException("Weight less than 0: " + entry);
+ } // else: weight == 0.0 is OK
+ }
+ return pick;
+ }
+
/**
* Returns a key from the supplied map according to a probability computed as
* the key's value divided by the total of all the key's values.
*
* @throws NullPointerException if the map is null.
* @throws IllegalArgumentException if the sum of the weights is not positive.
+ *
+ * @deprecated Use {@link #pick(Map, Object)} instead.
*/
+ @Deprecated
public T getWeighted (Map valuesToWeights)
{
// TODO: validate each weight to ensure it's not below 0