# Java 8 `forEach`

> 原文： [https://howtodoinjava.com/java8/foreach-method-example/](https://howtodoinjava.com/java8/foreach-method-example/)

Java `forEach`是一种工具方法，可迭代诸如（列表，集合或映射）和[流](https://howtodoinjava.com/java8/java-streams-by-examples/)之类的集合，并对它的每个元素执行特定操作。

## 1\. Java 8 `forEach` 方法

#### 1.1 `Iterable.forEach()`

下面的代码片段显示了[`Iterable`](https://howtodoinjava.com/java/collections/java-iterator/)接口中[`forEach`](https://docs.oracle.com/javase/8/docs/api/java/lang/Iterable.html#forEach-java.util.function.Consumer-)的默认实现。 它使`Iterable.forEach()`方法**可用于除`Map`** 之外的所有集合类。 下一节将讨论`Map`中的 *`forEach()`方法。*

```java
default void forEach(Consumer<? super T> action) {
    Objects.requireNonNull(action);
    for (T t : this) {
        action.accept(t);
    }
}

```

上面的方法*对`Iterable`的每个元素*执行给定的操作，直到所有元素都已处理或该操作引发异常。

`action`表示接受单个输入参数且不返回结果的操作。 它是`Consumer`接口的实例。

```java
List<String> names = Arrays.asList("Alex", "Brian", "Charles");

names.forEach(System.out::println);

//Console output
Alex
Brian
Charles

```

可以使用此简单语法创建**自定义消费者操作**。 这里`Object`类型应替换为集合或流中元素的类型。

```java
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

```

#### 1.2 `Map.forEach()`

此方法对此映射中的每个条目执行给定的 [`BiConsumer`](https://docs.oracle.com/javase/8/docs/api/java/util/function/BiConsumer.html) 操作，直到已处理所有条目或该操作引发异常。

```java
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);
    }
}

```

```java
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`示例类似，我们可以创建*自定义双消费者操作*，该操作从映射中获取键值对，然后一次处理每个条目。

```java
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);

```

程序输出。

```java
Key is : A
Value is : 1

Key is : B
Value is : 2

Key is : C
Value is : 3

```

## 2\.  使用`List`的`forEach`示例

Java 程序迭代流的所有元素并执行操作。 在此示例中，我们将打印所有偶数。

```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 );

```

程序输出：

```java
2
4

```

## 3\. 使用`Map`的`forEach`示例

我们已经看到上面的程序遍历[`HashMap`](https://howtodoinjava.com/java-hashmap/)的所有条目并执行操作。

我们还可以遍历映射键和值，并对所有元素执行任何操作。

```java
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);

```

程序输出：

```java
A=1
B=2
C=3

A
B
C

1
2
3

```

学习愉快！