В настоящее время я храню библиотеки маршаллинга для разных клиентских версий в 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.
Как мне получить желаемый результат (без повторного ввода всех записей и получения следующего "нижнего" значения каждый раз)?
Заранее спасибо!
Как мне получить желаемый результат (без повторения всех записей и последующего захвата "следующего более низкого" значения каждый раз)
Вы ничего не можете сделать для части "итерации через все записи": поскольку карта неупорядочена, нет возможности найти следующий более мелкий элемент без повторения всего набора ключей.
Тем не менее, вы можете сделать что-то о части "каждый раз": если вы сделаете копию этой карты в TreeMap
, вы сможете найти следующий более мелкий элемент, вызвав метод floorEntry
.
Другой альтернативой является копирование ключей в массив на стороне, сортировка массива и запуск двоичного поиска каждый раз, когда вам нужно найти следующий более мелкий ключ. С ключом в руке вы можете найти запись на своей карте хэша.
TreeMap
полностью сделал свое дело! Отлично, большое спасибо! Хотя мне нужен был floorEntry()
а не ceilingEntry()
.
Я рекомендую вам использовать 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