I want to get random keys and their respective values from a Map. The idea is that a random generator would pick a key and display that value. The tricky part is that both k
Use reservoir sampling to select a list of random keys, then insert them into a map (along with their corresponding values in the source map.)
This way you do not need to copy the whole keySet into an array, only the selected keys.
public static Map sampleFromMap(Map extends K, ? extends V> source, int n, Random rnd) {
List chosenKeys = new ArrayList();
int count = 0;
for (K k: source.keySet()) {
if (count++ < n) {
chosenKeys.add(k);
if (count == n) {
Collections.shuffle(chosenKeys, rnd);
}
} else {
int pos = rnd.nextInt(count);
if (pos < n) {
chosenKeys.set(pos, k);
}
}
}
Map result = new HashMap();
for (K k: chosenKeys) {
result.put(k, source.get(k));
}
return Collections.unmodifiableMap(result);
}