Вкл. SortedMap.subMap
Это API для SortedMap<K,V>.subMap
:
SortedMap<K,V> subMap(K fromKey, K toKey)
: Возвращает вид части этой карты, ключи которой находятся в диапазоне от fromKey
включительно до toKey
, исключая.
Эта всеобъемлющая нижняя граница, исключительная комбинированная верхняя граница («полуоткрытый диапазон») - это то, что распространено в Java, и, хотя она имеет свои преимущества, она также имеет свои причуды, как мы скоро увидим.
Следующий фрагмент иллюстрирует простое использование subMap
:
static <K,V> SortedMap<K,V> someSortOfSortedMap() {
return Collections.synchronizedSortedMap(new TreeMap<K,V>());
}
//...
SortedMap<Integer,String> map = someSortOfSortedMap();
map.put(1, "One");
map.put(3, "Three");
map.put(5, "Five");
map.put(7, "Seven");
map.put(9, "Nine");
System.out.println(map.subMap(0, 4));
// prints "{1=One, 3=Three}"
System.out.println(map.subMap(3, 7));
// prints "{3=Three, 5=Five}"
Последняя строка важна: 7=Seven
исключен из-за исключительной верхней границы subMap
. Теперь предположим, что нам на самом деле нужна верхняя граница включительно , тогда мы можем попытаться написать вспомогательный метод, подобный этому:
static <V> SortedMap<Integer,V>
subMapInclusive(SortedMap<Integer,V> map, int from, int to) {
return (to == Integer.MAX_VALUE)
? map.tailMap(from)
: map.subMap(from, to + 1);
}
Затем, продолжая приведенный выше фрагмент, мы получим:
System.out.println(subMapInclusive(map, 3, 7));
// prints "{3=Three, 5=Five, 7=Seven}"
map.put(Integer.MAX_VALUE, "Infinity");
System.out.println(subMapInclusive(map, 5, Integer.MAX_VALUE));
// {5=Five, 7=Seven, 9=Nine, 2147483647=Infinity}
Необходимо сделать пару ключевых замечаний:
- Хорошей новостью является то, что нам не важен тип значений, но ...
subMapInclusive
предполагает, что Integer
ключи для to + 1
работают.
- Универсальная версия, которая также принимает, например,
Long
Ключи невозможны (см. Связанные вопросы)
- Не говоря уже о том, что для
Long
нам нужно сравнить с Long.MAX_VALUE
вместо
- Перегрузки для числовых примитивов в штучной упаковке
Byte
, Character
и т. Д., Как ключи, все должны быть написаны индивидуально
- Специальная проверка должна быть сделана для
toInclusive == Integer.MAX_VALUE
, потому что +1
переполнится, а subMap
выдаст IllegalArgumentException: fromKey > toKey
- Это, вообще говоря, слишком уродливое и чрезмерно конкретное решение
- А как насчет
String
ключей? Или какой-то неизвестный тип, который может даже не быть Comparable<?>
?
Таким образом, вопрос заключается в следующем: можно ли написать общий метод subMapInclusive
, который принимает SortedMap<K,V>
и K fromKey, K toKey
и выполняет subMap
запросы с включенным диапазоном?
Похожие вопросы
Вкл. NavigableMap
Следует отметить, что существует перегрузка NavigableMap.subMap
, которая принимает две дополнительные переменные boolean
, чтобы указать, являются ли границы включающими или исключающими. Если бы это было доступно в SortedMap
, то ничего из вышеперечисленного даже не спросили бы.
Поэтому работа с NavigableMap<K,V>
для запросов с включенным диапазоном была бы идеальной, но в то время как Collections
предоставляет служебные методы для SortedMap
(среди прочего), нам не предоставляется такая же роскошь с NavigableMap
.
Похожие вопросы
В API, обеспечивающем только исключительные запросы верхнего диапазона
- Подсвечивает ли это проблему с исключительными запросами верхнего диапазона?
- Как в прошлом выполнялись запросы с включенным диапазоном, когда единственная доступная функциональность - исключительная верхняя граница?