Skip to content

Commit cf2e639

Browse files
committed
refractor:optimize file
1 parent b863b44 commit cf2e639

7 files changed

+139
-1138
lines changed

docs/java/What's New in JDK8/JDK8接口规范-静态、默认方法.md

-163
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
> 本文由 JavaGuide 翻译,原文地址:https://www.baeldung.com/foreach-java
2+
3+
## 1 概述
4+
5+
在Java 8中引入的*forEach*循环为程序员提供了一种新的,简洁而有趣的迭代集合的方式。
6+
7+
在本文中,我们将看到如何将*forEach*与集合*一起*使用,它采用何种参数以及此循环与增强的*for*循环的不同之处。
8+
9+
## 2 基础知识
10+
11+
```Java
12+
public interface Collection<E> extends Iterable<E>
13+
```
14+
15+
Collection 接口实现了 Iterable 接口,而 Iterable 接口在 Java 8开始具有一个新的 API
16+
17+
```java
18+
void forEach(Consumer<? super T> action)//对 Iterable的每个元素执行给定的操作,直到所有元素都被处理或动作引发异常。
19+
```
20+
21+
使用*forEach*,我们可以迭代一个集合并对每个元素执行给定的操作,就像任何其他*迭代器一样。*
22+
23+
例如,迭代和打印字符串集合*的*for循环版本:
24+
25+
```java
26+
for (String name : names) {
27+
System.out.println(name);
28+
}
29+
```
30+
31+
我们可以使用*forEach*写这个 :
32+
33+
```java
34+
names.forEach(name -> {
35+
System.out.println(name);
36+
});
37+
```
38+
39+
## 3.使用forEach方法
40+
41+
### 3.1 匿名类
42+
43+
我们使用 *forEach*迭代集合并对每个元素执行特定操作。**要执行的操作包含在实现Consumer接口的类中,并作为参数传递给forEach 。**
44+
45+
所述*消费者*接口是一个功能接口(具有单个抽象方法的接口)。它接受输入并且不返回任何结果。
46+
47+
Consumer 接口定义如下:
48+
49+
```java
50+
@FunctionalInterface
51+
public interface Consumer {
52+
void accept(T t);
53+
}
54+
```
55+
任何实现,例如,只是打印字符串的消费者:
56+
57+
```java
58+
Consumer<String> printConsumer = new Consumer<String>() {
59+
public void accept(String name) {
60+
System.out.println(name);
61+
};
62+
};
63+
```
64+
65+
可以作为参数传递给*forEach*
66+
67+
```java
68+
names.forEach(printConsumer);
69+
```
70+
71+
但这不是通过消费者和使用*forEach* API 创建操作的唯一方法。让我们看看我们将使用*forEach*方法的另外2种最流行的方式:
72+
73+
### 3.2 Lambda表达式
74+
75+
Java 8功能接口的主要优点是我们可以使用Lambda表达式来实例化它们,并避免使用庞大的匿名类实现。
76+
77+
由于 Consumer 接口属于函数式接口,我们可以通过以下形式在Lambda中表达它:
78+
79+
```java
80+
(argument) -> { body }
81+
name -> System.out.println(name)
82+
names.forEach(name -> System.out.println(name));
83+
```
84+
85+
### 3.3 方法参考
86+
87+
我们可以使用方法引用语法而不是普通的Lambda语法,其中已存在一个方法来对类执行操作:
88+
89+
```java
90+
names.forEach(System.out::println);
91+
```
92+
93+
## 4.forEach在集合中的使用
94+
95+
### 4.1.迭代集合
96+
97+
**任何类型Collection的可迭代 - 列表,集合,队列 等都具有使用forEach的相同语法。**
98+
99+
因此,正如我们已经看到的,迭代列表的元素:
100+
101+
```java
102+
List<String> names = Arrays.asList("Larry", "Steve", "James");
103+
104+
names.forEach(System.out::println);
105+
```
106+
107+
同样对于一组:
108+
109+
```java
110+
Set<String> uniqueNames = new HashSet<>(Arrays.asList("Larry", "Steve", "James"));
111+
112+
uniqueNames.forEach(System.out::println);
113+
```
114+
115+
或者让我们说一个*队列*也是一个*集合*
116+
117+
```java
118+
Queue<String> namesQueue = new ArrayDeque<>(Arrays.asList("Larry", "Steve", "James"));
119+
120+
namesQueue.forEach(System.out::println);
121+
```
122+
123+
### 4.2.迭代Map - 使用Map的forEach
124+
125+
Map没有实现Iterable接口,但它**提供了自己的forEach 变体,它接受BiConsumer***
126+
127+
```java
128+
Map<Integer, String> namesMap = new HashMap<>();
129+
namesMap.put(1, "Larry");
130+
namesMap.put(2, "Steve");
131+
namesMap.put(3, "James");
132+
namesMap.forEach((key, value) -> System.out.println(key + " " + value));
133+
```
134+
135+
### 4.3.迭代一个Map - 通过迭代entrySet
136+
137+
```java
138+
namesMap.entrySet().forEach(entry -> System.out.println(entry.getKey() + " " + entry.getValue()));
139+
```

0 commit comments

Comments
 (0)