タイトル通り、Java 8で追加されたFunction
が便利だったので書きます。
関数型インターフェース関連でとても参考になるページ
Java関数型インターフェースメモ(Hishidama's Java8 Functional Interface Memo)
Functionとは
Function<T,R>
は引数T
を受け取って戻り値R
を返す関数を変数っぽく扱えるものです。大体cの関数ポインタとか.Netのdelegate
みたいなもんです。
例えば以下の例では、func
はint
を受け取って処理を行い、int
を返します。
Function<Integer, Integer> func = input -> input * 3; //int inputに3を掛けたものが帰る func.apply(3); //呼び出し例、3 * 3 = 9が帰る
正直うまく書けて無いと思うので、以下の記事を参照してください。。。
www.atmarkit.co.jp
なにがうれしい?
同じxを入力とする一次関数と二次関数があり、それぞれパラメータはある程度一定であるような場合を例に書きます。結論のソースコード全体は一番下に置きます。
素直に書くと
素直に書くと以下のようになります。
変化するのはxだけなのに何度も何度も変数を書いて関数を呼び出して……というのは一々書くのがダサくて面倒くさいです。各関数のパラメータも、何らかのラベル付けをした方がTypoによる事故も起きにくいと思われます。
private static int linearFunction(int a, int b, int x){ return a * x + b; } private static int quadricFunction(int a, int p, int q, int x){ return a * (x - p) + q; } public static void main(String[] args) { int x = 2; System.out.println(linearFunction(1, 1, x)); System.out.println(quadricFunction(1, 1, 1, x)); }
Function + EnumMap
これをFunction + EnumMap
で書き直すと以下のようになります。
Enumでラベルを付けてマップに登録して呼び出してます。呼び出しがスッキリしたのとかはうれしいです。もうちょっといいやり方が有る気もしますがとりあえず気にしないことにします。
private enum e{ La1b2, Qa1p1q1, } private static int linearFunction(int a, int b, int x){ return a * x + b; } private static int quadricFunction(int a, int p, int q, int x){ return a * (x - p) + q; } private static final EnumMap<e, Function<Integer, Integer>> map; static { map = new EnumMap<>(e.class); map.put(e.La1b2, x -> linearFunction(1, 2, x)); map.put(e.Qa1p1q1, x -> quadricFunction(1, 1, 1, x)); } public static void main(String[] args) { System.out.println(map.get(e.La1b2).apply(2)); System.out.println(map.get(e.Qa1p1q1).apply(2)); }
ソースコード全体
import java.util.EnumMap; import java.util.function.Function; public class Main { private enum e{ La1b2, Qa1p1q1, } private static int linearFunction(int a, int b, int x){ return a * x + b; } private static int quadricFunction(int a, int p, int q, int x){ return a * (x - p) + q; } private static final EnumMap<e, Function<Integer, Integer>> map; static { map = new EnumMap<>(e.class); map.put(e.La1b2, x -> linearFunction(1, 2, x)); map.put(e.Qa1p1q1, x -> quadricFunction(1, 1, 1, x)); } private static Function<Integer, Integer> func = input -> input * 3; public static void main(String[] args) { System.out.println(map.get(e.La1b2).apply(2)); System.out.println(map.get(e.Qa1p1q1).apply(2)); } }