Если вы не возражаете против потраченного впустую пространства, один из подходов состоит в том, чтобы отдельно хранить List
всех ключей, которые находятся в Map
. Для лучшей производительности вам понадобится List
с хорошей производительностью произвольного доступа (например, ArrayList
). Затем просто получите случайное число от 0 (включительно) до list.size()
(исключая), вытащите ключ с этим индексом и посмотрите на него.
Random rand = something
int randIndex = rand.nextInt(list.size());
K key = list.get(randIndex);
V value = map.get(key);
Этот подход также означает, что добавление пары ключ-значение намного дешевле, чем ее удаление. Чтобы добавить пару ключ-значение, вы должны проверить, есть ли ключ на карте (если ваши значения могут быть нулевыми, вам придется отдельно вызывать map.containsKey
; если нет, вы можете просто добавить ключ- пара значений и посмотрите, является ли «старое значение», которое он возвращает, null)
. Если ключ уже находится на карте, список не изменяется, но если нет, вы добавляете ключ в список (операция O (1) большинство списков.) Однако для удаления пары ключ-значение требуется операция O (N) для удаления ключа из списка.
Если пространство представляет большую проблему, но производительность ниже, вы также можете получить Iterator
над набором записей карты (Map.entrySet()
) и пропустить randIndex
записей перед возвратом нужного. Но это будет операция O (N), которая как бы побеждает всю точку карты.
Наконец, вы можете просто получить набор входных данных toArray()
и случайным образом внести в него индекс. Это проще, хотя и менее эффективно.