LoginSignup
2
0

More than 5 years have passed since last update.

はじめてのGOLD「Function」

Posted at

関数型インターフェースの話をします。
突然ですが、以下のコードを見てください。

Func.java

interface Foo {
    public Function<String,String> doIt(Function<Integer,String> f);
}
Main.java
Foo foo = f -> x -> "ABC" + f.apply(x.length());
System.out.println(foo.doIt(x -> x + "$").apply("DEF"));

これはラムダ式です。
ラムダ式の基本に立ち返って、Main.javaを省略せずに書いてみます。

Main.java

Foo foo = 
    (Function<Integer,String> f) ->
        {return (String x) -> {return "ABC" + f.apply(x.length());};}

長くなって余計にわからなくなったかもしれませんが、これを部分で見ていきます。
ポイントは、
・どのラムダ式がどの関数型インターフェースの定義をしているのか
・ある時点での戻り値を把握する
の二点だと思います。なので常にこれを意識していきます。

上記のコードは、冒頭の
public Function<String,String> doit(Function<Integer,String> f)
の定義です。

ですので、引数がFunction<Integer,String>となります。
このFunctionの定義はまだしていない、ということを確認してください。

次に戻り値Function<String,String>を見てみます。

(String x) -> {return "ABC" + f.apply(x.length());}

String型を引数にとり、String型を返します。
戻り値のFunctionの処理はここで定義されました。

doItの定義と、doItの戻り値の定義が行われました。
次に引数Function<Integer,String>の定義です。
これはMain.javaの2行目で行っています。

foo.doIt(x -> x + "$").apply("DEF")

x -> x + "$" がそれです。
あえて書き直すと、

foo.doIt((Integer x) -> {return x + "$";}).apply("DEF")

となります。
Integer型を引数に、String型を返しています。

それぞれの定義を確認したところで、値の流れを見てみます。

まず、doIt()が呼ばれ、関数の定義(x -> x +"$")を渡します。
そして、また別の関数の定義(x -> "ABC" + f.apply(x.length()))を戻します。

doItが実行された時点では、まだ値は関数の定義のままです。

doIt()に連なっているapply("DEF")を実行することで具体的な値が生まれます。

doIt()から戻ってきたFunction<String,String>の引数に"DEF"が渡ります。

値を代入してみると、

"ABC" + f.apply("DEF".length())

ということになります。

"DEF".length()のInteger型を利用して、引数のFunction<Integer,String> fが実行されます。

"DEF".length() + "$"

ここではString型の"3$"が戻ります。
すると、doIt()の戻り関数は

"ABC" + "3$"

となり、最終的な値は"ABC3$"です。

ラムダの中のラムダを説明してみました。
何かご意見や補足あれば、よろしくお願いいたします。

2
0
0

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
2
0