Получить SubMap из Map в Java

В Java подкарта — это часть или часть заданной Карты между ключами определенного диапазона. В этой статье будут рассмотрены различные методы получения подкарты из Карты.

1. Использование Map.keySet().retainAll()

RetainAll() удаляет все ключи из Map, которых нет в указанном списке. Будьте осторожны, remainAll() удаляет записи из исходной коллекции, поэтому, если мы не хотим изменять исходную Map, выполните эту операцию на новой копии Map.

Map<String, String> map = new HashMap<>();map.put("key1", "Value1");map.put("key2", "Value2");map.put("key3", "Value3");List<String> keysToRetain = List.of("key1", "key2");map.keySet().retainAll(keysToRetain);System.out.println(map); //{key1=Value1, key2=Value2}

2. Использование TreeMap submap(), headMap() и tailMap()

Класс TreeMap хранит пары ключ-значение , отсортированные по ключам в естественном порядке или с использованием поставщика Comparator для пользовательских порядков. TreeMap позволяет получить подкарту с помощью следующих методов.

  • subMap(fromKey, toKey): возвращает представление части этой карты, ключи которой находятся в диапазоне от fromKey(включительно) до toKey(исключительно).
  • headMap(toKey): возвращает представление части этой карты, ключи которой строго меньше toKey.
  • tailMap(fromKey): возвращает представление части этой карты, ключи которой больше или равны fromKey.

Мы также можем использовать эти методы с другими реализациями Map SortedMap и NavigableMap.

TreeMap<String, String> treeMap = new TreeMap<>();treeMap.put("key1", "Value1");treeMap.put("key2", "Value2");treeMap.put("key3", "Value3");SortedMap<String, String> subMap = treeMap.subMap("key2", "key3"); //{key2=Value2}SortedMap<String, String> headMap = treeMap.headMap("key2"); //{key1=Value1}SortedMap<String, String> tailMap = treeMap.tailMap("key2"); //{key2=Value2, key3=Value3}

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

subMap.put("key2", "NEW_VALUE_2");System.out.println(subMap); //{key2=NEW_VALUE_2}System.out.println(treeMap); //{key1=Value1, key2=NEW_VALUE_2, key3=Value3}

Аналогично, добавление новых записей в исходную карту также изменит представления карты. Например, добавление новой пары ключ-значение key4:value4 в исходную карту отразится во всех представлениях подкарт.

treeMap.put("key4", "value4");System.out.println(tailMap); //{key2=NEW_VALUE_2, key3=Value3, key4=value4}System.out.println(treeMap); //{key1=Value1, key2=NEW_VALUE_2, key3=Value3, key4=value4}

См. также: HashMap против TreeMap

3. Использование потокового API

Поток — это коллекция или последовательность данных из источника. Мы можем использовать API потока для обхода, фильтрации и сбора желаемых пар ключ-значение в новую карту.

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

Map<Integer, String> hashmap = new HashMap<>();hashmap.put(1, "Value1");hashmap.put(2, "Value2");hashmap.put(3, "Value3");List<Integer> keysList = Arrays.asList(1, 2);Map<Integer, String> subHashmap = hashmap.entrySet().stream().filter(x -> keysList.contains(x.getKey())).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));System.out.println(subHashmap); //{1=Value1, 2=Value2}

4. Использование класса Maps Guava

Guava — это набор стандартных библиотек, который предоставляет различные методы утилит. Его класс Maps предоставляет следующие методы утилит для получения новой Карты путем фильтрации ключей или значений из указанной Карты.

  • Maps.filterKeys(нефильтрованнаяКарта, ключПредикат)
  • Maps.filterValues(нефильтрованнаяКарта, значениеПредикат)
  • Maps.filterEntries(нефильтрованнаяКарта, entryPredicate)

В каждом методе мы передаем исходную карту и предикат, который соответствует ключу, значению или записи для заполнения в подкарте.

Map<Integer, String> hashmap = new HashMap<>();hashmap.put(1, "Value1");hashmap.put(2, "Value2");hashmap.put(3, "Value3");List<Integer> keysList = Arrays.asList(1, 2);Map<Integer, String> subMap = Maps.filterKeys(hashmap, Predicates.in(keysList));System.out.print(subMap); //{1=Value1, 2=Value2}

5. Заключение

В этом руководстве по Java мы научились получать подкарту из указанной Карты, используя различные методы от API карт и API потоков до методов Guava filter(). Чтобы получить подкарту, независимую от исходной Карты, нам нужно перебрать записи Карты и создать новую Карту из выбранных записей.

Приятного обучения!!

Исходный код на Github

Прокрутить вверх