声明三个实体类
专辑实体类:Album
@Data
//专辑 若干曲目构成
public class Album {
private String name; //专辑名
private List<Track> tracks; //专辑中所有曲目的列表
private List<Artist> artists; //参与创作本专辑的艺术家列表
private Stream<Artist> musicians;
}
创作者实体类:Artist
@Data
//创作音乐的个人或团队
public class Artist {
private String name; //艺术家名字
private String member; //乐队成员
private String origin; //乐队来自哪里
}
专辑中的代表作实体类:Track
@Data
//专辑中的一支曲目
public class Track {
private String name; //曲目名称
}
对实体类进行初始化
List<Artist>allArtist = new ArrayList<>();
for (int i = 0; i < 5; i++) {
Artist artist = new Artist();
artist.setName("张"+i+"乐队");
artist.setMember("张"+i+"、z"+i+"、章"+i);
artist.setOrigin("London"+i);
allArtist.add(artist);
}
Artist artist = new Artist();
artist.setName("李四最牛逼的乐队");
artist.setMember("自己一个");
artist.setOrigin("China");
allArtist.add(artist);
List<Track> trackList = new ArrayList<>();
for (int i = 0; i < 5; i++) {
Track track = new Track();
track.setName("断桥"+i);
trackList.add(track);
}
List<Album> albumList = new ArrayList<>();
for (int i = 0; i < 5; i++) {
Album album = new Album();
album.setName("自由式"+i);
album.setMusicians(allArtist.stream());
album.setArtists(allArtist);
album.setTracks(trackList);
albumList.add(album);
}
System.out.println("allArtist"+allArtist);
System.out.println("------------------");
System.out.println("trackList"+trackList);
System.out.println("------------------");
System.out.println("album"+albumList);
System.out.println("------------------");
需求:根据一组专辑album找出以"2"为结尾的曲目track
原始代码:双重for循环和if语句进行筛选↓↓↓
// 原始代码 遗留代码
public static Set<String> findLongTracks(List<Album> albums) {
Set<String> trackNames = new HashSet<>();
for (Album album : albums){
for(Track track : album.getTracks()){
if(track.getName().endsWith("2")){
String name = track.getName();
trackNames.add(name);
}
}
}
return trackNames;
}
初步优化:代码重构1 初步使用流
// 代码重构1:初步使用流
public static Set<String> findLongTracks(List<Album> albums) {
Set<String> trackNames = new HashSet<>();
albums.stream()
.forEach(album -> album.getTracks()
.forEach(track ->{
if(track.getName().endsWith("2")){
String name = track.getName();
trackNames.add(name);
}
}));
return trackNames;
}
再优化: 代码重构2 流操作替换内层循环
// 代码重构2:流操作替换内层循环
public static Set<String> findLongTracks(List<Album> albums){
Set<String> trackNames = new HashSet<>();
albums.forEach(album -> {
album.getTracks()
.stream().filter(track -> track.getName().endsWith("2"))
.map(track -> track.getName() + "-" + track.getClass())
.forEach(trackNames::add);
});
return trackNames;
}
进一步优化:代码重构3 使用flatMap将多个流合并并返回,同时将forEach替换为flatMap
public static Set<String> findLongTracks(List<Album> albums) {
Set<String> trackNames = new HashSet<>();
albums.stream()
.flatMap(album -> album.getTracks().stream())
.filter(track -> track.getName().endsWith("2"))
.map(Track::getName)
.forEach(trackNames ::add);
return trackNames;
}
深度优化:代码重构4 完全使用流操作 将最后的forEach方法替换成collect(toSet())
public static Set<String> findLongTracks(List<Album> albums) {
return albums.stream()
.flatMap(album -> album.getTracks().stream())
.filter(track -> track.getName().endsWith("2"))
.map(Track::getName)
.collect(toSet());
}
创建Test执行类执行上述代码
System.out.println("以2为结尾的Track名为" + findLongTracks(albumList));
结果均为:
由此可见经过一系列代码重构让代码更符合流的风格,提高了代码的可读性。
----记录学习 新手博主 多多包涵