-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathCourse4Refactoring.java
99 lines (85 loc) · 3.69 KB
/
Course4Refactoring.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
package com.java8.lambda.chapter3;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import com.java8.lambda.chapter1.Album;
import com.java8.lambda.chapter1.Track;
/**
* 重构遗留代码
*
* 编写示例代码的每一步都要进行单元测试,保证代码能够正常工作。
* @author hzweiyongqiang
*
*/
public class Course4Refactoring {
// 假定选定一组专辑,找出其中所有长度大于 1 分钟的曲目名称。
// 遗留代码:找出长度大于 1 分钟的曲目
public Set<String> findLongTracks0(List<Album> albums){
Set<String> trackNames = new HashSet<>(); // 保存找到的曲目名称
for (Album album : albums) { // 遍历所有专辑
for (Track track : album.getTrackList()) { // 遍历每张专辑上的每首曲目
if (track.getLength() > 60) { // 检查其长度是否大于 60 秒
String name = track.getName();
trackNames.add(name);
}
}
}
return trackNames;
}
// 重构的第一步:找出长度大于 1 分钟的曲目
// 使用 Stream 的 forEach 方法替换掉 for 循环,但还是暂时保留原来循环体中的代码
public Set<String> findLongTracks1(List<Album> albums){
Set<String> trackNames = new HashSet<>(); // 保存找到的曲目名称
albums.stream()
.forEach(album -> { // 遍历所有专辑
album.getTracks()
.forEach(track->{ // 遍历每张专辑上的每首曲目
if (track.getLength() > 60) {// 检查其长度是否大于 60 秒
String name = track.getName();
trackNames.add(name);
}
});
});
return trackNames;
}
// 重构的第二步:找出长度大于 1 分钟的曲目
// 最内层的 forEach 方法有三个功用:
// 找出长度大于 1 分钟的曲目,得到符合条件的曲目名称,将曲目名称加入集合 Set 。
// 这就意味着需要三项 Stream 操作:
// 找出满足某种条件的曲目是 filter 的功能,得到曲目名称则可用 map 达成,终结操作可使用 forEach 方法将曲目名称加入一个集合。
public Set<String> findLongTracks2(List<Album> albums){
Set<String> trackNames = new HashSet<>(); // 保存找到的曲目名称
albums.stream()
.forEach(album -> { // 遍历所有专辑
album.getTracks()
.filter(track -> track.getLength() > 60)
.map(track -> track.getName())
.forEach(name -> trackNames.add(name));
});
return trackNames;
}
// 重构的第三步:找出长度大于 1 分钟的曲目
// 将专辑转化成一个曲目的 Stream
// 任何时候想转化或替代代码,都该使用 map 操作。
// 使用比 map 更复杂的 flatMap 操作,把多个 Stream 合并成一个 Stream 并返回。
public Set<String> findLongTracks3(List<Album> albums){
Set<String> trackNames = new HashSet<>(); // 保存找到的曲目名称
albums.stream()
.flatMap(album -> album.getTracks())
.filter(track -> track.getLength() > 60)
.map(track -> track.getName())
.forEach(name -> trackNames.add(name));
return trackNames;
}
// 重构的第四步:找出长度大于 1 分钟的曲目
// 使用 collect(Collectors.toSet()) 将 Stream 中的值转换成一个集合。
// 因此,将最后的 forEach 方法替换为 collect ,并删掉变量 trackNames
public Set<String> findLongTracks4(List<Album> albums){
return albums.stream()
.flatMap(album -> album.getTracks())
.filter(track -> track.getLength() > 60)
.map(track -> track.getName())
.collect(Collectors.toSet());
}
}