そらとぶへび

仕事・プライベートを通しての気づき、JavaやPHP、データベースやサーバの話などこつこつと書いていきます

ラムダ式その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