# Java `forEach`教程

原文：http://zetcode.com/java/foreach/

Java `forEach`教程显示了如何使用 Java8 `forEach()`方法。 我们与消费者合作，并在列表，映射和集合集合上展示`forEach()`。

`forEach()`方法是 Java8 中引入的。它为程序员提供了一种新的，简洁的迭代集合的方法。

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

```java
void forEach(Consumer<? super T> action);

```

这是`forEach()`方法的语法。

## `Consumer`接口

`Consumer`接口是一个函数式接口（具有单个抽象方法的接口），它接受单个输入并且不返回结果。

```java
@FunctionalInterface
public interface Consumer {
    void accept(T t);
}

```

这是`Consumer`接口的定义。

`com/zetcode/JavaForEachListConsumer.java`

```java
package com.zetcode;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;

public class JavaForEachListConsumer {

    public static void main(String[] args) {

        List<String> items = new ArrayList<>();

        items.add("coins");
        items.add("pens");
        items.add("keys");
        items.add("sheets");

        items.forEach(new Consumer<String>() {
            @Override
            public void accept(String name) {
                System.out.println(name);
            }
        });
    }
}

```

在此示例中，我们使用`forEach()`遍历字符串列表。 Java lambda 表达式可以缩短此语法。

## Lambda 表达式

Lambda 表达式主要用于定义函数式接口的内联实现，即仅具有单个方法的接口。 Lambda 表达式是使用`->` lambda 运算符创建的。

`com/zetcode/JavaForEachListLambda.java`

```java
package com.zetcode;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;

public class JavaForEachListLambda {

    public static void main(String[] args) {

        List<String> items = new ArrayList<>();

        items.add("coins");
        items.add("pens");
        items.add("keys");
        items.add("sheets");

        items.forEach((String name) -> {
            System.out.println(name);
        });
    }
}

```

这里我们有同样的例子。 lambda 表达式使示例更简洁。

## Java 映射上的`forEach`

以下示例在映射上使用`forEach()`。

`com/zetcode/JavaForEachMap.java`

```java
package com.zetcode;

import java.util.HashMap;
import java.util.Map;

public class JavaForEachMap {

    public static void main(String[] args) {

        Map<String, Integer> items = new HashMap<>();

        items.put("coins", 3);
        items.put("pens", 2);
        items.put("keys", 1);
        items.put("sheets", 12);

        items.forEach((k, v) -> {
            System.out.printf("%s : %d%n", k, v);
        });
    }
}

```

我们有一个字符串/整数对的映射。 使用`forEach()`方法，我们遍历映射并打印其键/值对。

在下一个示例中，我们在代码中显式显示`Consumer`和`Map.Entry`。

`com/zetcode/JavaForEachMap2.java`

```java
package com.zetcode;

import java.util.HashMap;
import java.util.Map;
import java.util.function.Consumer;

public class ForEachMap2 {

    public static void main(String[] args) {

        HashMap<String, Integer> map = new HashMap<>();

        map.put("cups", 6);
        map.put("clocks", 2);
        map.put("pens", 12);

        Consumer<Map.Entry<String, Integer>> action = entry ->
        {
            System.out.printf("key: %s", entry.getKey());
            System.out.printf(" value: %s%n", entry.getValue());
        };

        map.entrySet().forEach(action);
    }
}

```

该示例在一个条目集上循环，该条目集是通过`entrySet()`检索的。

## Java 集合上的`forEach`

以下示例在一个集合上使用`forEach()`。

`com/zetcode/JavaForEachSet.java`

```java
package com.zetcode;

import java.util.HashSet;
import java.util.Set;

public class JavaForEachSet {

    public static void main(String[] args) {

        Set<String> brands = new HashSet<>();

        brands.add("Nike");
        brands.add("IBM");
        brands.add("Google");
        brands.add("Apple");

        brands.forEach((e) -> { System.out.println(e); });
    }
}

```

我们有一组字符串。 使用`forEach()`方法，我们遍历集合并打印其值。

## 在数组上使用 forEach

以下示例在数组上使用`forEach()`。

`com/zetcode/JavaForEachArray.java`

```java
package com.zetcode;

import java.util.Arrays;

public class JavaForEachArray {

    public static void main(String[] args) {

        int[] nums = { 3, 4, 2, 1, 6, 7 };

        Arrays.stream(nums).forEach((e) -> { System.out.println(e); });
    }
}

```

在示例中，我们有一个整数数组。 我们使用`Arrays.stream()`方法将数组转换为流。 然后`forEach()`方法遍历元素并将它们打印到控制台。

## 过滤列表

在使用`forEach()`遍历数据之前，我们可以轻松过滤数据。

`com/zetcode/JavaForEachListFilter.java`

```java
package com.zetcode;

import java.util.ArrayList;
import java.util.List;

public class JavaForEachListFilter {

    public static void main(String[] args) {

        List<String> items = new ArrayList<>();

        items.add("coins");
        items.add("pens");
        items.add("keys");
        items.add("sheets");

        items.stream().filter(item -> (item.length() == 4)).forEach(System.out::println);
    }
}

```

在此示例中，我们过滤字符串列表，并将过滤后的列表打印到控制台。 仅显示具有四个字符的字符串。

## `IntConsumer`，`LongConsumer`，`DoubleConsumer`

从 Java8 开始，我们为原始数据类型内置了使用者接口：`IntConsumer`，`LongConsumer`和`DoubleConsumer`。

`com/zetcode/JavaForEachConsSpec.java`

```java
package com.zetcode;

import java.util.Arrays;
import java.util.function.DoubleConsumer;
import java.util.function.IntConsumer;
import java.util.function.LongConsumer;

public class JavaForEachConsSpec {

    public static void main(String[] args) {

        int[] inums = { 3, 5, 6, 7, 5 };
        IntConsumer icons = i -> System.out.print(i + " ");
        Arrays.stream(inums).forEach(icons);

        System.out.println();

        long[] lnums = { 13L, 3L, 6L, 1L, 8L };
        LongConsumer lcons = l -> System.out.print(l + " ");
        Arrays.stream(lnums).forEach(lcons);

        System.out.println();

        double[] dnums = { 3.4d, 9d, 6.8d, 10.3d, 2.3d };
        DoubleConsumer dcons = d -> System.out.print(d + " ");
        Arrays.stream(dnums).forEach(dcons);

        System.out.println();
    }
}

```

在示例中，我们创建了三种类型的使用者，并使用`forEach()`对其进行了迭代。

在本教程中，我们介绍了 Java8 `forEach()`方法。 我们已经介绍了使用者，并在列表，映射和集合上使用了`forEach()`。

您可能也对以下相关教程感兴趣： [Java 教程](/lang/java/)，[用 Java8 的`StringJoiner`连接字符串](/articles/java8stringjoiner/)，[Google Guava 简介](/articles/guava/)，[Java 过滤列表](/java/filterlist/)或 [Android 教程](/mob/android/)中的代码。

列出[所有 Java 教程](/all/#java)。