フィールド名、及び getter / setter が同じ Java Bean のコピーも、Collector.of のサンプルとして
以下のように書ける。
public static<T,U> U fieldcopy(T t, U u){ UnaryOperator<String> topUpper = s->s.substring(0, 1).toUpperCase() + s.substring(1); return Arrays.stream(t.getClass().getDeclaredFields()).map(f->f.getName()).collect( Collector.of(()->u, (r, n)->{ try{ Method getter = t.getClass().getDeclaredMethod( (t.getClass().getDeclaredField(n).getType().equals(boolean.class) ? "is" : "get") + topUpper.apply(n) ); Method setter = r.getClass().getDeclaredMethod( "set"+ topUpper.apply(n), getter.getReturnType() ); setter.invoke(r, getter.invoke(t)); }catch(SecurityException | NoSuchFieldException | NoSuchMethodException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e){ throw new RuntimeException(e); } }, (a, b)->a, a->a) ); }
これは、完全に同じフィールド、同じ getter / setter メソッドがあるのが前提である。
以前、yipuran-core で FieldUtil なるものを作り、
yipuran-core/FieldUtil.java at master · yipuran/yipuran-core · GitHub
public static <R, T> R copy(T t, Supplier<R> s)
public static <R, T> R copylenient(T t, Supplier<R> s)
というメソッドを作ったが、
フィールド名、及び getter / setter が同じという約束なら、上の Collector.of の方が良いような気がしてきた。
継承 extends がある場合は、別途工夫が必要ではある。