私が作った Fieldsetter 以下は、
https://github.com/yipuran/yipuran-core/blob/master/src/main/java/org/yipuran/util/Fieldsetter.java
https://github.com/yipuran/yipuran-core/wiki#fieldsetter
フィールド名称を指定する点で、タイプセーフではない。
名称を誤ってもコンパイルエラーにはならないからだ。
とは言え、new 演算子コンストラクタで生成したインスタンス変数に、
setter を大量に実行するのも読みやすいかもしれないが、
そういう new で生成してセットするしたものを沢山書くと、
変数が沢山、生まれてしまい、それも嫌だという我儘がある。
つまり、以下のようなものを沢山書きたくない。
Foo foo1 = new Foo(); foo1.setId(1001); foo1.setName("Yip1"); foo1.setLocate("Tokyo"); Foo foo2 = new Foo(); foo2.setId(1002); foo2.setName("Yip2"); foo2.setLocate("Yokohama");
考えて次のように、UnaryOperator の代わりに、
Fuction<T, T> を生成する関数型インターフェースを用意する。
import java.util.function.Function; @FunctionalInterface public interface ObjectSetter<T, U>{ void accept(T t, U u); public static <T, U> Function<T, T> of(ObjectSetter<T, U> osetter, U u){ return t->{ osetter.accept(t, u); return t; }; } }
これを、Optional の map メソッドに渡して最後に、get() でsetter実行済のインスタンスを
取得するのだ。
例) ( サンプルなので、ここでの記述量を少なくするために lombok を使用した対象クラス)
import lombok.Data; @Data public class Foo{ private Integer id; private String name; private String locate; }
これを、java.util.Optional と ObjectSetter で以下のように setter実行済を取得する。
Foo foo = Optional.of(new Foo()) .map(ObjectSetter.of(Foo::setId, 1001)) .map(ObjectSetter.of(Foo::setName, "Yip1")) .map(ObjectSetter.of(Foo::setLocate, "Tokyo")) .get();
わざわざ、こんなことする理由は、new 演算子で生成した変数のsetterメソッドを実行するのを
回避したいだけですが、これは、以下のようにさらに結果を次のメソッドの引数に渡す時など、
よけいな変数宣言をしなくて済む。
List<Foo> list = new ArrayList<>(); // list.add( Optional.of(new Foo()) .map(ObjectSetter.of(Foo::setId, 1001)) .map(ObjectSetter.of(Foo::setName, "Yip1")) .map(ObjectSetter.of(Foo::setLocate, "Tokyo")) .get() );
結局、この ObjectSetter は、
yipuran-core で、AcceptFunction として、
用意してある。
yipuran-core/AcceptFunction.java at master · yipuran/yipuran-core · GitHub