Skip to content

Instantly share code, notes, and snippets.

@qbosen
Last active August 14, 2020 03:10
Show Gist options
  • Save qbosen/27c877db116bc860bd48dfe43e288a28 to your computer and use it in GitHub Desktop.
Save qbosen/27c877db116bc860bd48dfe43e288a28 to your computer and use it in GitHub Desktop.
属性条件复制的链式操作
import javax.annotation.Nullable;
import java.util.Arrays;
import java.util.Collection;
import java.util.Map;
import java.util.Optional;
import java.util.function.BiConsumer;
import java.util.function.BiPredicate;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collectors;
/**
* @author qiubaisen
* @date 2020/8/13
*/
public class FluentPropertySetter {
public static <S, D, ID> Function<D, S> closureProvider(Map<ID, S> source, Function<D, ID> idGen) {
return data -> source.get(idGen.apply(data));
}
public static <S, D, ID> Function<D, S> closureProvider(Collection<S> source, Function<S, ID> sourceId, Function<D, ID> destId) {
return closureProvider(source.stream().collect(Collectors.toMap(sourceId, Function.identity())), destId);
}
public static <S, D, ID> Supplier<Function<D, S>> lazyProvider(Supplier<Collection<S>> source, Function<S, ID> sourceId, Function<D, ID> destId) {
return () -> closureProvider(source.get(), sourceId, destId);
}
/**
* 对{@code getter}的结果进行再包装
*/
public static <S, D, PROP> BiConsumer<S, D> transfer
(Function<S, PROP> getter, BiConsumer<D, PROP> setter, Function<PROP, PROP> propMapper) {
return transfer(getter, setter, null, (s, d) -> true, propMapper);
}
public static <S, D, PROP> BiConsumer<S, D> transfer
(Function<S, PROP> getter, BiConsumer<D, PROP> setter) {
return transfer(getter, setter, (Supplier<PROP>) null);
}
public static <S, D, PROP> BiConsumer<S, D> transfer
(Function<S, PROP> getter, BiConsumer<D, PROP> setter, BiPredicate<S, D> modifyCondition) {
return transfer(getter, setter, null, modifyCondition);
}
/**
* 条件判断后进行消费
*
* @param getter 获取方法, 结果为null时进行默认值设置
* @param setter 设置方法
* @param defaultProp 默认值, null表示不进行默认值设置。默认值设置在{@code source/getter}结果为空时发生
* @param modifyCondition 条件满足时,进行属性设置,否则跳过。参与判断的参数可能为{@code null}
* @param <S> source, null时进行默认值设置
* @param <D> dest
* @param <PROP> 属性值类型
* @return 属性设置方法
*/
public static <S, D, PROP> BiConsumer<S, D> transfer
(Function<S, PROP> getter, BiConsumer<D, PROP> setter, @Nullable Supplier<PROP> defaultProp, BiPredicate<S, D> modifyCondition) {
return (s, d) -> {
if (modifyCondition.test(s, d)) transfer(getter, setter, defaultProp).accept(s, d);
};
}
/**
* 根据条件判断是否设置属性。对于source/getterResult/propResult为null的情况进行默认值设置
*
* @param getter 获取方法, 结果为null时进行默认值设置
* @param setter 设置方法
* @param defaultProp 默认值, null表示不进行默认值设置。默认值设置在{@code source/getter}结果为空时发生
* @param modifyCondition 条件满足时,进行属性设置,否则跳过。参与判断的参数可能为{@code null}
* @param propMapper 属性映射, 对getter结果进行映射,如果getter结果为null,则进行默认值配置
* @param <S> source, null时进行默认值设置
* @param <D> dest
* @param <PROP> 属性值类型
* @return 属性设置函数
*/
public static <S, D, PROP> BiConsumer<S, D> transfer
(Function<S, PROP> getter, BiConsumer<D, PROP> setter, @Nullable Supplier<PROP> defaultProp, BiPredicate<S, D> modifyCondition, Function<PROP, PROP> propMapper) {
return transfer(getter.andThen(v -> v == null ? null : propMapper.apply(v)), setter, defaultProp, modifyCondition);
}
/**
* 值转移设置
*
* @param getter 获取方法, 结果为null时进行默认值设置
* @param setter 设置方法
* @param defaultProp 默认值, null表示不进行默认值设置。默认值设置在{@code source/getter}结果为空时发生
* @param <S> source,null时进行默认值设置
* @param <D> dest, null时跳过设置
* @param <PROP> getter,setter进行交互的属性值类型
* @return 对source, dest进行设置的函数
*/
public static <S, D, PROP> BiConsumer<S, D> transfer(Function<S, PROP> getter, BiConsumer<D, PROP> setter, @Nullable Supplier<PROP> defaultProp) {
return (source, dest) -> {
if (dest == null) return;
Optional<PROP> prop = Optional.ofNullable(source).map(getter);
if (prop.isPresent()) {
setter.accept(dest, prop.get());
} else {
if (defaultProp == null) return;
setter.accept(dest, defaultProp.get());
}
};
}
@SafeVarargs
public static <S, D> Function<D, D> propertyTransfer
(Function<D, S> provider, BiConsumer<S, D>... transfers) {
return propertyTransfer(() -> provider, transfers);
}
@SafeVarargs
public static <S, D> Function<D, D> propertyTransfer
(Supplier<Function<D, S>> lazyProvider, BiConsumer<S, D>... transfers) {
return data -> {
Arrays.stream(transfers).reduce(BiConsumer::andThen).ifPresent(trans -> trans.accept(lazyProvider.get().apply(data), data));
return data;
};
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment