Используйте что-то вроде
private static final List<BiConsumer<Entity,Entity>> ACCESSORS =
Collections.unmodifiableList(Array.asList(
(src,dst) -> dst.setAreaCode(src.getAreaCode()),
(src,dst) -> dst.setOtherProperty(src.getOtherProperty())
/* etc */
));
Затем вы можете перебрать список и применить каждую операцию к двум объектам, например
static final void copyAll(Entity src, Entity dst) {
ACCESSORS.forEach(op -> op.accept(src, dst));
}
Ключевым моментом является то, что фактическое значение свойстваТип обрабатывается внутри каждого BiConsumer
, но больше не является частью общей сигнатуры и, следовательно, не должен быть объявлен для ACCESSORS
.Это еще более эффективно, так как он может обрабатывать примитивные типы данных без дополнительных затрат.
Map
не была подходящей структурой данных для этой задачи, так как для этих функций никакой значимый поиск не мог быть выполнен,так что это структура данных, предназначенная только для итерации.
Вы можете интегрировать логику «копировать только при ненулевом» с универсальным вспомогательным методом:
private static final List<BiConsumer<Entity,Entity>> ACCESSORS =
Collections.unmodifiableList(Arrays.asList(
copyWhenNonNull(Entity::getAreaCode, Entity::setAreaCode),
copyWhenNonNull(Entity::getOtherProperty, Entity::setOtherProperty)
/* etc */
));
private static <E,V> BiConsumer<E,E> copyWhenNonNull(
Function<? super E, ? extends V> getter, BiConsumer<? super E, ? super V> setter) {
return (src,dst) -> {
V value = getter.apply(src);
if(value != null) setter.accept(dst, value);
};
}
The copyAll
метод не меняется.Это даже позволяет смешивать безусловное копирование свойств, которое никогда не может быть null
с условным копированием.