0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Javaで関数型言語のreduceを実装してみる part2

Posted at

※この文章はまだ書きかけです

始めに

前回の投稿のコメントでの指摘を修正したソースをアップしています。
また、reduceを実装して感じたことをまとめます。

前回の投稿の修正

Javaで関数型言語のreduceを実装してみるのコメント欄で指摘のあった点を踏まえてソースを修正しました

reduceを実装して感じたこと

以下の観点でまとめます
- 末尾再帰と最適化
- ループは直感的ではない(個人的な主観です。異論はたくさんあると思います。)
- データ構造を探索する人と探索した人が見つけたものを使う人

修正後のソース

FuncTest.java
package test;

import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Deque;
import java.util.List;

public class FuncTest {
    static public class Reduce<T>{
        //外部に公開するメソッドはpublicにする
        public T reduce(Collection<T> b,Function<T> f){
            return reduce(b,f,null);
        }
        //内部のロジックを処理するの使うメソッドはprivateにする
        private  T reduce(Collection<T> b,Function<T> f,T t){
            Deque<T> a = new ArrayDeque<T>(b);
            //スタックの要素がなくなったら再帰処理を終了する
            if(a.size()==0){
                return t;
            }
            //要素数1のリストが渡された場合
            else if (a.size() == 1){
                //最初に再帰処理が呼び出された時の処理
                if(t==null)return a.pop();
                //2回目以降に再帰処理が呼び出された場合は引数で渡された合計値と
                //スタックの先頭を引数で渡されたインナークラスのメソッドに渡す
                else{ t = f.aply(t,a.pop());}
            }
            //要素数2以上のリストが渡された場合
            else
            {
                //最初に再帰処理が呼び出された時の処理
                //Stackの一番目と2番目を引数にセットする
                if(t==null){t = f.aply(a.pop(),a.pop());}
                //2回目以降に再帰処理が呼び出された場合は引数で渡された合計値と
                //スタックの先頭を引数で渡されたインナークラスのメソッドに渡す
                else{t = f.aply(t,a.pop());}
            }
            return reduce(a,f,t) ;
        }
    }

    //Functionクラスのインターフェイス abstractクラスで定義する
    static  abstract class Function<T>{
        public abstract T aply(T a, T b);
    }
    //配列の中身をすべて足し算します
    static class  FunctionAsAdd<T> extends Function<Integer>{
        public Integer aply(Integer a, Integer b){return a+b;};
    }
    //配列の中身をすべて掛け算します
    static class FunctionAsMultiplication<T> extends Function<Integer>{
        public Integer aply(Integer a, Integer b){return a*b;};
    }
    //配列の文字列をすべて連結します
    static class FunctionAsString<T> extends Function<String>{
        public String aply(String a, String b){return a+b;};
    }

    public static void main(String args[]){
        List<Integer>list = new ArrayList<Integer>();
        Collections.addAll(list, 1,2,3,4,5,6,7,8,9,10);
        System.out.println(
                (new Reduce<Integer>())
                .reduce(list,new FunctionAsAdd<Integer>())
                );//55が表示される
        System.out.println((new Reduce<Integer>())
                .reduce(list,new FunctionAsMultiplication<Integer>())
                );//3628800が表示される
        List<String> stringList= Arrays.asList( 
                new String[]{"1","2","3","4","5","6","7","8","9"});
        System.out.println((new Reduce<String>())
                .reduce(stringList,new FunctionAsString<String>())
                );//123456789が表示される
    }
}
0
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?