Java forEach — это служебный метод для итерации по коллекции(список, набор или карта) и потоковой передачи, и выполнение определенного действия над каждым его элементом.
Iterable.forEach()
Ниже приведен фрагмент кода, показывающий реализацию forEach по умолчанию в интерфейсе Iterable . Это делает Iterable.forEach() доступным для всех классов коллекции, кроме Map . Метод forEach() в Map обсуждается в следующем разделе.
default void forEach(Consumer<? super T> action) {
Objects.requireNonNull(action);
for (T t : this) {
action.accept(t);
}
}
Указанный выше метод выполняет данное действие для каждого элемента Iterable пока все элементы не будут обработаны или действие не вызовет исключение.
action представляет операцию, которая принимает один входной аргумент и не возвращает результата. Это пример Consumer интерфейса.
List<String> names = Arrays.asList("Alex", "Brian", "Charles");
names.forEach(System.out::println);
//Console output
Alex
Brian
Charles
Пользовательское действие потребителя может быть создано с использованием этого простого синтаксиса. Здесь тип Object должен быть заменен типом элементов в коллекции или потоке.
List<String> names = Arrays.asList("Alex", "Brian", "Charles");
Consumer<String> makeUpperCase = new Consumer<String>()
{
@Override
public void accept(String t)
{
System.out.println(t.toUpperCase());
}
};
names.forEach(makeUpperCase);
//Console output
ALEX
BRIAN
CHARLES
Map.forEach()
Этот метод выполняет заданное действие BiConsumer для каждой записи в этой карте, пока все записи не будут обработаны или действие не вызовет исключение.
default void forEach(BiConsumer<? super K, ? super V> action) {
Objects.requireNonNull(action);
for (Map.Entry<K, V> entry : entrySet()) {
K k;
V v;
try {
k = entry.getKey();
v = entry.getValue();
} catch(IllegalStateException ise) {
// this usually means the entry is no longer in the map.
throw new ConcurrentModificationException(ise);
}
action.accept(k, v);
}
}
Map<String, String> map = new HashMap<String, String>();
map.put("A", "Alex");
map.put("B", "Brian");
map.put("C", "Charles");
map.forEach((k, v) ->
System.out.println("Key = " + k + ", Value = " + v));
//Console Output
Key = A, Value = Alex
Key = B, Value = Brian
Key = C, Value = Charles
Как и в примере со List , мы можем создать собственное действие двоякого потребителя, беря пары ключ-значение из карты и обрабатывая каждую запись по одной за раз.
BiConsumer<String, Integer> action = (a, b) ->
{
System.out.println("Key is : " + a);
System.out.println("Value is : " + b);
};
Map<String, Integer> map = new HashMap<>();
map.put("A", 1);
map.put("B", 2);
map.put("C", 3);
map.forEach(action);
Программа вывода.
Key is : A Value is : 1 Key is : B Value is : 2 Key is : C Value is : 3
Пример Java forEach с использованием List
Java-программа для перебора всех элементов потока и выполнения действий. В этом примере мы печатаем все четные числа.
List<Integer> numberList = Arrays.asList(1,2,3,4,5);
Consumer<Integer> action = System.out::println;
numberList.stream()
.filter(n -> n%2 == 0)
.forEach( action );
Программа вывода.
2 4
Пример с использованием Map
Мы уже видели вышеупомянутую программу для перебора всех записей HashMap и выполнения действия.
Мы также можем перебирать ключи и значения карты и выполнять любые действия со всеми элементами.
HashMap<String, Integer> map = new HashMap<>();
map.put("A", 1);
map.put("B", 2);
map.put("C", 3);
//1. Map entries
Consumer<Map.Entry<String, Integer>> action = System.out::println;
map.entrySet().forEach(action);
//2. Map keys
Consumer<String> actionOnKeys = System.out::println;
map.keySet().forEach(actionOnKeys);
//3. Map values
Consumer<Integer> actionOnValues = System.out::println;
map.values().forEach(actionOnValues);
Программа вывода.
A=1 B=2 C=3 A B C 1 2 3
