「java 8関数式プログラミング」-関数式プログラミングを使用してコードを再構築

3907 ワード

レガシーコード:長さが1分以上の曲を見つける
public Set findLongTracks(List albums){
    Set tracksNames=new HashSet<>();
    for(Album album:albums){
        for(Track track:album.getTrackList()){
            if(track.getLength()>60){
                String name=track.getName();
                trackNames.add(name);
            }
        }
    }
    return trackNames;
}

最初のステップの再構築
public Set findLongTracks(List albums){
    Set tracksNames=new HashSet<>();
    //      getTracks       Stream  
    albums.stream()
            .forEach(album->{
                album.getTracks()
                        .forEach(track->{
                            if(track.getLength()>60){
                                    trackNames.add(track.getNames)
                                        }
                                   });//          ?
                 });
    return trackNames;
}

第2ステップの再構築
public Set findLongTracks(List albums){
    Set tracksNames=new HashSet<>();
    albums.stream()
            .forEach(album->{
                album.getTracks()
                        .filter(track->track.getLength()>60)
                        .map(track->track.getName())
                        .forEach(name->trackNames.add(name));
                 });
    return trackNames;
}

第3ステップの再構築
public Set findLongTracks(List albums){
    Set tracksNames=new HashSet<>();
    //   Stream     
    albums.stream()
            .flatMap(album->album.getTracks()).
                        .filter(track->track.getLength()>60)
                        .map(track->track.getName())
                        .forEach(name->trackNames.add(name));
    return trackNames;
}

ステップ4の再構築
public Set findLongTracks(List albums){
    return albums.stream()
                .flatMap(album->album.getTracks()).
                        .filter(track->track.getLength()>60)
                        .map(track->track.getName())
                        .collect(toSet());
}

Lambda式の目的は変数ではなく値を取得することです!だから、できるだけゴミ変数を発生させないで中間結果を保存します.本の上の1段の説明:Lambda式はデータの上の操作を説明して、どのように転化するかを説明するのではなく、どのように転化するかを明確にしました.このように書かれたコードは、欠陥が少ない.この言葉をどう理解しますか.
これは、プロセスではなく、元のデータから結果に変換することに重点を置くべきであり、データ変換プロセスを暴露しない(すなわち、一連の中間変数を生成する)こと、すなわち、データがどのように変換されたかを説明する必要はなく、最終的に変換が達成されればよいことを示している.
どのように変換するかを明確にするのではなく、どのように変換するかを説明する別の意味は、書かれた関数に副作用がないことです.(副作用のない関数はプログラムや外部の状態を変えることはありません)
したがって,Lambda式をStream上の高次関数に伝達する場合,副作用はできるだけ避けるべきである.唯一の例外はforEachメソッドで、彼は終結メソッドです.