1. Обзор
В этом кратком руководстве мы рассмотрим различные способы перебора записей Map
в Java.
Проще говоря, мы можем извлечь содержимое карты
с помощью entrySet()
, keySet()
или values()
. Поскольку это все наборы, ко всем из них применяются одинаковые принципы итерации.
Давайте подробнее рассмотрим некоторые из них.
2. Краткое введение в методы Map
entrySet (), keySet()
и values()
Прежде чем мы перейдем к карте, используя три метода, давайте разберемся, что эти методы делают:
entrySet()
– возвращает коллекцию-представление карты, элементы которой взяты изкласса Map.Entry
. Методentry.getKey()
возвращает ключ, аentry.getValue()
возвращает соответствующее значение.keySet ()
— возвращает все ключи, содержащиеся в этой карте, в виденабора
values ()
— возвращает все значения, содержащиеся в этой карте, в виденабора
Далее давайте посмотрим на эти методы в действии.
3. Использование цикла for
3.1. Использование набора записей()
Во-первых, давайте посмотрим, как перебирать Map
с помощью Entry
Set
:
public void iterateUsingEntrySet(Map<String, Integer> map) {
for (Map.Entry<String, Integer> entry : map.entrySet()) {
System.out.println(entry.getKey() + ":" + entry.getValue());
}
}
Здесь мы извлекаем множество
записей из нашей карты
, а затем перебираем их, используя классический подход для каждого.
3.2. Использование набора ключей()
В качестве альтернативы мы можем сначала получить все ключи в нашей карте
с помощью метода keySet
, а затем перебрать карту по каждому ключу:
public void iterateUsingKeySetAndForeach(Map<String, Integer> map) {
for (String key : map.keySet()) {
System.out.println(key + ":" + map.get(key));
}
}
3.3. Перебор значений с использованием values()
Иногда нас интересуют только значения на карте, независимо от того, какие ключи с ними связаны . В этом случае values()
— наш лучший выбор:
public void iterateValues(Map<String, Integer> map) {
for (Integer value : map.values()) {
System.out.println(value);
}
}
4. Итератор
Другой подход к выполнению итерации — использование Iterator
. Далее давайте посмотрим, как методы работают с объектом Iterator .
4.1. Итератор
и entrySet()
Во-первых, давайте пройдемся по карте, используя Iterator и entrySet()
:
public void iterateUsingIteratorAndEntry(Map<String, Integer> map) {
Iterator<Map.Entry<String, Integer>> iterator = map.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, Integer> entry = iterator.next();
System.out.println(entry.getKey() + ":" + entry.getValue());
}
}
Обратите внимание, как мы можем получить экземпляр Iterator
, используя API iterator()
набора
, возвращаемого entrySet().
Затем, как обычно, мы перебираем итератор
с помощью iterator.next().
4.2. Итератор
и keySet()
Точно так же мы можем перебирать карту
с помощью Iterator
и keySet()
:
public void iterateUsingIteratorAndKeySet(Map<String, Integer> map) {
Iterator<String> iterator = map.keySet().iterator();
while (iterator.hasNext()) {
String key = iterator.next();
System.out.println(key + ":" + map.get(key));
}
}
4.3. Итератор
и значения()
Мы также можем пройтись по значениям карты, используя итератор
и метод values()
:
public void iterateUsingIteratorAndValues(Map<String, Integer> map) {
Iterator<Integer> iterator = map.values().iterator();
while (iterator.hasNext()) {
Integer value = iterator.next();
System.out.println("value :" + value);
}
}
5. Использование Lambdas и Stream API
Начиная с версии 8, Java представила Stream API и лямбда-выражения. Далее давайте посмотрим, как итерировать карту, используя эти методы.
5.1. Использование forEach()
и Lambda
Как и большинство других вещей в Java 8, это оказалось намного проще, чем альтернативы. Мы просто воспользуемся методом forEach()
:
public void iterateUsingLambda(Map<String, Integer> map) {
map.forEach((k, v) -> System.out.println((k + ":" + v)));
}
В этом случае нам не нужно преобразовывать карту в набор записей. Чтобы узнать больше о лямбда-выражениях, мы можем начать здесь .
Мы можем, конечно, начать с ключей, чтобы перебрать карту:
public void iterateByKeysUsingLambda(Map<String, Integer> map) {
map.keySet().foreach(k -> System.out.println((k + ":" + map.get(k))));
}
Точно так же мы можем использовать ту же технику с методом values()
:
public void iterateValuesUsingLambda(Map<String, Integer> map) {
map.values().forEach(v -> System.out.println(("value: " + v)));
}
5.2. Использование потокового
API
Stream
API — одна из важных функций Java 8. Мы также можем использовать эту функцию для циклического просмотра карты
.
Stream
API следует использовать, когда мы планируем выполнять дополнительную обработку Stream
; в противном случае это просто forEach()
, как описано ранее.
Давайте возьмем entrySet()
в качестве примера, чтобы увидеть, как работает Stream
API:
public void iterateUsingStreamAPI(Map<String, Integer> map) {
map.entrySet().stream()
// ... some other Stream processings
.forEach(e -> System.out.println(e.getKey() + ":" + e.getValue()));
}
Использование Stream
API с методами keySet()
и values()
будет очень похоже на пример выше.
6. Заключение
В этой статье мы сосредоточились на критической, но простой операции: переборе элементов карты
.
Мы рассмотрели несколько методов, которые можно использовать только с Java 8+, а именно лямбда-выражения и Stream
API.
Как всегда, примеры кода в этой статье можно найти на GitHub .