Field 属性が、Snake case で記述された Java のオブジェクト(Bean)と
Camel case で記述された Java のオブジェクト(Bean)
相互に値をコピー生成する方法、
つまり、Snake case で記述されたフィールド属性値を対応する Camel case で記述されたフィールド属性値にセットして
オブジェクトを生成する。また、その逆である。
昨日の投稿、
Java で、Snake case ⇔ Camel case - Oboe吹きプログラマの黙示録
から、思いつくコードである。
フィールド属性値 Get / Set や、Throwable な関数型インターフェースを使用、
GitHub - yipuran/yipuran-core: Java application framework
を利用する。
Snake case → Camel case
import java.util.Arrays; import java.util.HashMap; import java.util.Map; import java.util.Optional; import java.util.regex.Pattern; import org.yipuran.function.ThrowableBiConsumer; import org.yipuran.function.ThrowableConsumer; import org.yipuran.function.ThrowableSupplier; import org.yipuran.util.Fieldsetter; import org.yipuran.util.GenericBuilder;
public static <R, T> R copySnakeToCamel(T t, Class<R> cls){ Map<String, String> fmap = Arrays.stream(cls.getDeclaredFields()) .map(e->e.getName()) .collect(()->new HashMap<String, String>(), (r, s)->r.put(s, s), (r, s)->{}); GenericBuilder<R> builder = Arrays.stream(t.getClass().getDeclaredFields()) .collect(ThrowableSupplier.to(()->GenericBuilder.of(ThrowableSupplier.to(()->cls.newInstance()))) , ThrowableBiConsumer.of((r, f)->{ f.setAccessible(true); String camel = Optional.of(Pattern.compile("_") .splitAsStream(f.getName().toLowerCase()).filter(e->e.length() > 0) .collect(StringBuilder::new , (rr, tt)->rr.append(tt.substring(0, 1).toUpperCase()).append(tt.substring(1)) , (v, w)->{}).toString()).filter(e->e.length() > 1) .map(e->e.substring(0, 1).toLowerCase() + e.substring(1)).get(); if (fmap.containsKey(camel)){ r.with(Fieldsetter.of((p, u)->camel), f.get(t)); } }), (r, s)->{}); return builder.build(); }
Camel case → Snake case
import java.util.Arrays; import java.util.HashMap; import java.util.Map; import org.yipuran.function.ThrowableBiConsumer; import org.yipuran.function.ThrowableSupplier; import org.yipuran.util.Fieldsetter; import org.yipuran.util.GenericBuilder;
public static <R, T> R copyCamelToSnake(T t, Class<R> cls){ Map<String, String> fmap = Arrays.stream(cls.getDeclaredFields()) .map(e->e.getName()) .collect(()->new HashMap<String, String>(), (r, s)->r.put(s.toLowerCase(), s), (r, s)->{}); GenericBuilder<R> builder = Arrays.stream(t.getClass().getDeclaredFields()) .collect(ThrowableSupplier.to(()->GenericBuilder.of(ThrowableSupplier.to(()->cls.newInstance()))) , ThrowableBiConsumer.of((r, f)->{ f.setAccessible(true); String snake = f.getName().replaceAll("([a-z0-9]+)([A-Z]+)", "$1_$2").toLowerCase(); if (fmap.containsKey(snake)){ r.with(Fieldsetter.of((p, u)->snake), f.get(t)); } }), (r, s)->{}); return builder.build(); }