再帰呼出しをするように関数型インターフェースを書くまでもない、
単にメソッド宣言を省略するだけの目的で考える。
再帰と言っても、実際の仕事の機会では、フィボナッチ数列を求めるような機会よりも
処理が遅くてもいい探索目的の機会の方が多い。
例題(簡単に紹介するための例題)
以下 Item オブジェクトの親子関係のリストからルートを求める
public class Item{ public int id; public String name; public Integer parent; public Item(int id, String name, Integer parent){ this.id = id; this.name = name; this.parent = parent; } }
要件発生の都度、再帰メソッドを書く場合、、
static Item getRoot(Item item, List<Item> list){ if (item==null || item.parent==null) return item; return getRoot(list.stream().filter(e->e.id==item.parent).findAny().orElse(null), list); }
ジェネリックとBiFunction , Predicate で再帰メソッドを定義
import java.util.function.BiFunction; import java.util.function.Predicate; /** * Refrain */ public interface Refrain{ public static <T, U> T call(T t, U u, BiFunction<T, U, T> f, Predicate<T> p){ T r = f.apply(t, u); if (p.test(r)) return r; return call(r, u, f, p); } }
呼出し例
List<Item> list = new ArrayList<>(); list.add(new Item(1, "A", null)); list.add(new Item(2, "B", 1)); list.add(new Item(3, "C", 2)); list.add(new Item(4, "D", 3));
Item root = Refrain.call(item, list , (t, u)->u.stream().filter(e->t.parent != null && e.id==t.parent).findAny().orElse(null) , e->e==null || e.parent==null);
Refrain と、いいかげんに名前をつけました。
ふと、頭の中で浮かんだのが、ユーミンの「リフレインが、」・・・
世代がバレてしまいますね。