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 流操作姿势还不学习一下

lambda表达式与Stream流(非io)

JAVA由一个将JSONArray转成Map的需求引发的lambda语法的学习

java基础复习

Java高阶进阶之Java函数式编程-Stream流-Lambda表达式

Java高阶进阶之Java函数式编程-Stream流-Lambda表达式