Map<String, Object> に、クラスの属性名と値が格納されているとして、
Map entrySet() → Stream の collect で、Fieldsetter 実行してインスタンスを生成
ここで使用するものは、
https://github.com/yipuran/yipuran-core/wiki#genericbuildert
と、
https://github.com/yipuran/yipuran-core/blob/master/src/main/java/org/yipuran/util/Fieldsetter.java
例)
public class Iteminfo{ public String a; public int b; public String c; public LocalDate d; }
Map<String, Object> map = new HashMap<String, Object>(); map.put("a", "A"); map.put("b", 246); map.put("c", "C"); map.put("d", LocalDate.now());
Map entrySet() → Stream の collect → Supplier で GenericBuilder を提供して、
accumulator 処理 で、GenericBuilder の with でセッターを実行する
Iteminfo info = map.entrySet().stream()
.collect(()->GenericBuilder.of(Iteminfo::new),
(r, t)->r.with(Fieldsetter.of((p, u)->t.getKey()), t.getValue()), (r, t)->{})
.build();
最後に、build() で生成する。
検証
System.out.println("a = " + info.a ); System.out.println("b = " + info.b ); System.out.println("c = " + info.c ); System.out.println("d = " + info.d );
結果
a = A b = 246 c = C d = 2019-09-11
大量に、クラスのフィールドが存在して、フィールド値を格納したインスタンスを
生成するのには、有効な手段になりそうだ。
JSON テキストから、Google gson の fromJson を使う場面に近い方法だが、
ストリームの collect で生成のビルダの準備までやる上の方法は、
意外と使える方法かもしれない。