今日の自分を支える 技術→マネジメント

技術職→管理職になりました

関数オブジェクト

変数に関数を格納したもの。 いつの間にかjavaでもできるようになっていたらしい。

そもそも関数とは?

入力(Input)、処理(Process)、出力(Output)を備えるもの。名前は必要ない。
メソッドは関数の一種で、クラスに属するという特性を持っている。

関数オブジェクトとは?

変数に格納された関数のこと。実際には関数への参照を変数に格納する。

変数へのメソッド参照の格納方法

変数名 = クラス名::そのクラスの静的メソッド名
変数名 = インスタンス変数名::そのインスタンスのメソッド名

変数に格納した関数の呼び出し方法

関数を格納した変数の名前.SAMインタフェースのメソッド名(引数)
※SAMインタフェースについては後述

実装例

import java.util.function.*;

public class Main{
     
    public static int sub(int a, int b){
        return a-b;
    }
    
    public static void main(String[] args){
        //関数オブジェクトの作成
        IntBinaryOperator func = Main::sub;
        //関数の実行
        int a = func.applyAsInt(5,3);
    }
}

関数オブジェクトを格納する型

格納する関数と同じ引数、戻り値のメソッドを持つSAMインタフェースの変数に格納する。

SAMインタフェースとは

抽象メソッド1つしか持たないインタフェースのこと。

public interface TestFunction {
    public abstract int call(int x, int y);
}

インタフェース名は自由、メソッド名や引数の変数名は格納予定の関数と同じでなくてよい。

汎用API

関数格納のために汎用APIが用意されている。
上記実装例のIntBinaryOperator もその一つ。

補足

高階関数

関数を引数として受け取る関数のこと。

(XXXFunc a, int b) -> {
  return func.applyAsInt(a) +func.applyAsInt(a);
};