Lambda表达式学习篇三(流-下)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Lambda表达式学习篇三(流-下)相关的知识,希望对你有一定的参考价值。
一、重构遗留代码
为了进一步解释如何重构一流代码,本节将距离说明如何将一段使用循环进行集合操作的代码,重构成基于Stream的操作。
假定选取一组专辑,找出其中所有长度大于一分钟的曲目名称。下面是一个例子,首先初始化一个set对象,用来保存找到的曲目名称。然后使用for循环遍历所有专辑,每次循环中在使用一个for循环遍历每张专辑的每首曲目,检查其长度是否大于60秒,如果是,则将该曲目的名称加入set对象。
例如:遗留代码:找出代码大于一分钟的曲目
1 private static Set<String> findLongTracks(List<Album> albums) 2 { 3 Set<String> trackNames=new HasSet(); 4 for(Album album:albums) 5 { 6 for(Track track:album.getTrackList()) 7 { 8 if(track.getLength()>60) 9 { 10 String name=track.getName(); 11 trackNames.add(name); 12 } 13 } 14 15 } 16 return trackNames; 17 }1、重构第一步
public Set<string> findLongTracks(List<Album> albums)
{
Set<String> trackNames=new HashSet<>();
albums.stream()
.forEach(album->{
album.getTracks()
.forEach(treack->{
if(track.getLength()>60)
{
string name =track.getName();
trackNames.add(name);
}
});
});
return trackNames;
}
在本次重构中,虽然用了流,但是没有发挥它的作用。事实上,重构后的代码还不如原来代码。
因此,要继续重构我们就应该找突破口,其中最内层的foreach就是突破口。最内层的foreach方法有三个功用:找出长度大于一分钟的曲目,得到符合条件的曲目名称,将曲目名称加入集合Set。这就意味着需要三项Stream的操作:
①找出满足条件的曲目是filter功能;
②得到曲目名称是map功能;
③终结操作可使用foreach方法将曲目名称加入一个集合。
2、重构的第二步
public Set<String> findLongTreacks(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));
}
);
}
虽然做了改进但是代码还是很冗长。
理想的操作,莫过于找到一种方法,将专辑转化一个曲目的stream。任何时候想转换或者替代代码,都该使用map操作。这里将使用比map更复杂的flatMap操作,把多个Stream合并成一个Stream并返回。将foreach方法替换成flatMap后。
3、重构代码的第三部
public Set<String> findLongTracks(List<Album> albums) { Set<String> trackName=new HaashSet(); albums.stream() .flatmap(album->album.getTracks()) .filter(track->track.getLength()>60) .map(track->track.getName()) .foreach(name->trackName.add(name)); return trackNames; }
上面的代码中使用一组简洁的方法调用替换掉了两个嵌套的for循环,看起来清晰许多。但是我们还可以继续修改,继续替换到最后一个for循环。
4、重构代码
public Set<String> findLongTracks(List<Album> albums){ return
album.stream() .flatMao(album->album.getTracks()) .filter(track->track.getLength()>60) .map(track->track.getName()) .collect(toSet()); }
以上是关于Lambda表达式学习篇三(流-下)的主要内容,如果未能解决你的问题,请参考以下文章
还看不懂同事的代码?超强的 Stream 流操作姿势还不学习一下
JAVA由一个将JSONArray转成Map的需求引发的lambda语法的学习