码迷,mamicode.com
首页 > 其他好文 > 详细

Lambda表达式学习篇三(流-下)

时间:2017-06-10 19:23:18      阅读:140      评论:0      收藏:0      [点我收藏+]

标签:ack   调用   hashset   stat   距离   static   lock   log   return   

 

一、重构遗留代码

  为了进一步解释如何重构一流代码,本节将距离说明如何将一段使用循环进行集合操作的代码,重构成基于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表达式学习篇三(流-下)

标签:ack   调用   hashset   stat   距离   static   lock   log   return   

原文地址:http://www.cnblogs.com/lambda-learning-1/p/6979186.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!