HashMap: найти следующую нижнюю клавишу

1

В настоящее время я храню библиотеки маршаллинга для разных клиентских версий в HashMap. Библиотеки загружаются с использованием API org.reflections. Для простоты я просто вставлю несколько значений здесь вручную. Они неупорядочены по намерениям, потому что я не влияю на то, в каком порядке инициализируется карта при запуске с помощью API отражений. Ключи (ClientVersion) - это перечисления.

HashMap<ClientVersion, IMarshalLib> MAP = new HashMap<>();
MAP.put(ClientVersion.V100, new MarshalLib100());
MAP.put(ClientVersion.V110, new MarshalLib110());
MAP.put(ClientVersion.V102, new MarshalLib102());
MAP.put(ClientVersion.V101, new MarshalLib101());
MAP.put(ClientVersion.V150, new MarshalLib150());

Все, и до сих пор, проблема в том, что есть клиентские версии там, где маршаллинг не изменился с предыдущей версии.

Скажем, у нас есть клиентская версия ClientVersion.V140. В этом конкретном случае я ищу MarshalLib110, назначенный ClientVersion.V110.

Как мне получить желаемый результат (без повторного ввода всех записей и получения следующего "нижнего" значения каждый раз)?

Заранее спасибо!

  • 1
    Ты не можешь Используйте TreeMap.
Теги:
hashmap

2 ответа

3
Лучший ответ

Как мне получить желаемый результат (без повторения всех записей и последующего захвата "следующего более низкого" значения каждый раз)

Вы ничего не можете сделать для части "итерации через все записи": поскольку карта неупорядочена, нет возможности найти следующий более мелкий элемент без повторения всего набора ключей.

Тем не менее, вы можете сделать что-то о части "каждый раз": если вы сделаете копию этой карты в TreeMap, вы сможете найти следующий более мелкий элемент, вызвав метод floorEntry.

Другой альтернативой является копирование ключей в массив на стороне, сортировка массива и запуск двоичного поиска каждый раз, когда вам нужно найти следующий более мелкий ключ. С ключом в руке вы можете найти запись на своей карте хэша.

  • 1
    TreeMap полностью сделал свое дело! Отлично, большое спасибо! Хотя мне нужен был floorEntry() а не ceilingEntry() .
  • 0
    Примечание: метод floorKey (..) «возвращает наименьший ключ, больший или равный данному ключу»: потолокKey (102) возвращает 102.
0

Я рекомендую вам использовать NavigableSet. Посмотрите на этот пример:

    HashMap<Integer, String> map = new HashMap<>();
    map.put(100, "MarshalLib100");
    map.put(110, "MarshalLib110");
    map.put(102, "MarshalLib102");
    map.put(101, "MarshalLib101");
    map.put(150, "MarshalLib150");

    NavigableSet<Integer> set = new TreeSet<>(map.keySet());

    Integer key = set.lower(150);   // ^ -> 110
    String  val = map.get(key);     // ^ -> MarshalLib110

    // or
    key = set.higher(110);// ^ -> 150
    val = map.get(key);   // ^ -> MarshalLib150

Обновление: использование TreeMap для поиска следующего нижнего ключа не совсем корректно. Пример:

    TreeMap<Integer, String> treeMap = new TreeMap<Integer, String>();
    treeMap.put(100, "MarshalLib100");
    treeMap.put(110, "MarshalLib110");
    treeMap.put(102, "MarshalLib102");
    treeMap.put(101, "MarshalLib101");
    treeMap.put(150, "MarshalLib150");

    System.out.println(treeMap.floorKey(102));
    System.out.println(treeMap.floorEntry(102)); 
    System.out.println(treeMap.ceilingKey(102));
    System.out.println(treeMap.ceilingEntry(102));

Вывод:

102
102=MarshalLib102
102
102=MarshalLib102
  • 0
    Это кажется довольно сложным, потому что в качестве номеров версий я использую не целые числа, а перечисление версий.
  • 0
    Это не имеет значения, поскольку ваш ключевой класс реализует интерфейс Comparable.
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню