ラムダ式その1
ラムダ式はメソッド定義を式として記述できるJava8以降の言語仕様。ラムダ式を使うことで、クラスやインタフェースより小さな粒度の振る舞いを抽象化することができる。
public class Main { @FunctionalInterface interface Appender{ public void app(StringBuffer sb,String s); } public static void main(String[] args) { Appender appender = (sb,s) -> sb.append(s); StringBuffer result = new StringBuffer(); appender.app(result, "aaa"); appender.app(result, "bbb"); System.out.println(result); } }
ラムダ式の文法
(仮引数列)-> {処理本体の文(複数)}
または
(仮引数列)-> 処理本体の式
(int x,int y) -> {return x + y;}
または
(int x,int y) -> x + y
// 仮引数の型名は省略できる。すべてを省略するかすべてを省略しないのどちらか。 (x,y) -> x + y // 仮引数が一つの場合は丸括弧を省略できる。 x -> x + 1 // 仮引数が一もない場合は場合は丸括弧は省略できない。 () -> 1 // 中括弧でくくった場合、returnする必要がある。 x -> {return x + 1;} // 中括弧でくくった場合、複数行の記述が可能。 x -> { x + 1; return x; }
ラムダ式とローカル変数の関係
import java.util.function.Consumer; public class Main { // Consumerは標準関数型インタフェースの一つ(入力があり、出力なし) Consumer<String> createProc(String paramValue){ String localValue = "local"; Consumer<String> proc = s-> System.out.println("s:"+ s + ",paramValue:" + paramValue +",localValue:" + localValue); return proc; } public static void main(String[] args) { Main ma1 = new Main(); Consumer<String> proc = ma1.createProc("aaaa"); // ラムダ式メソッドの実行 proc.accept("bbbb"); } }
実行結果
s:bbbb,paramValue:aaaa,localValue:local
標準関数型インタフェース
java.utilfunctionパッケージで定義される関数型インタフェース。
Function | R apply(T t) | T型オブジェクトによる入力、R型オブジェクトの出力 |
Predicate | boolean test(T t) | T型オブジェクトによる入力、boolean型の出力 |
Consumer | void accept(T t) | T型オブジェクトによる入力、出力なし |
Supplier | T get() | 入力なし、T型オブジェクトの出力 |
標準型インタフェースで初めの処理を書き直した例
import java.util.function.*; public class Main { public static void main(String[] args) { IntFunction<StringBuffer> create = StringBuffer::new; StringBuffer sb = create.apply(8); Function<String, StringBuffer> appender = sb::append; appender.apply("abc"); BiConsumer<StringBuffer, String> appender2 = StringBuffer::append; appender2.accept(sb, "def"); System.out.println(sb); } }
実行結果
abcdef