PropertyMapper
背景
最近开始研究 kafka ,发现了一个有意思的类 PropertyMapper。
内部使用了函数式编程,再次不做深入讲解,若对函数式编程不理解的小伙伴,可以先取了解一下。
它是啥
它是一个String 的工具类,用于将值从提供的源映射到目标。
再这过程中,可以对值进行调整以及判断。
START
它有啥
构造
大伙看到这层嵌套,是不是觉得有点装饰器的味道了<( ̄ˇ ̄)/
上面说了,它在赋值的过程中是可以对值进行调整以及判断,那么用了装饰者,就可以在定义一个带有规则的 PropertyMapper 基础上对它进行更多的职能赋值~
SourceOperator
这是一个 source(PropertyMapper 定义 待会会介绍到) 的操作接口,对传入的值进行自定义的逻辑处理。
Source
- supplier 需要处理的来源值
- predicate 自定义的校验逻辑
它咋用
from
public <T> Source<T> from(Supplier<T> supplier) {
Assert.notNull(supplier, "Supplier must not be null");
Source<T> source = getSource(supplier);
if (this.sourceOperator != null) {
source = this.sourceOperator.apply(source);
}
return source;
}
这个方法会将传入的值进行封装,封装成source对象,进行相对应的赋值以及自定义的校验判断。
to
public void to(Consumer<T> consumer) {
Assert.notNull(consumer, "Consumer must not be null");
T value = this.supplier.get();
if (this.predicate.test(value)) {
consumer.accept(value);
}
}
这方法将最终校验过的值,赋值给消费者。
when
public Source<T> when(Predicate<T> predicate) {
Assert.notNull(predicate, "Predicate must not be null");
return new Source<>(this.supplier, predicate);
}
此方法使用频率较高,传入自定义的逻辑校验。
as
public <R> Source<R> as(Function<T, R> adapter) {
Assert.notNull(adapter, "Adapter must not be null");
Supplier<Boolean> test = () -> this.predicate.test(this.supplier.get());
Predicate<R> predicate = (t) -> test.get();
Supplier<R> supplier = () -> {
if (test.get()) {
return adapter.apply(this.supplier.get());
}
return null;
};
return new Source<>(supplier, predicate);
}
此方法 传入的是 Function ,会处理你想要将值进行你想要的操作。那么我们来实际操作一下。
开始用
public void testPropertyMapper(String source, List<String> target) {
PropertyMapper propertyMapper = PropertyMapper.get();
propertyMapper.from(source)
.when((x) -> x.length() > 4)
.as(x -> x + "asd")
.to(target::add);
}
如上,这段代码就会将长度大于4的字符串,加上 “asd” 后,添加到 target 中。
ps(别说java 8 的 stream 也可以做到!!别钻牛角尖!!!)
它也提供了一个校验非 null 的方法
PropertyMapper.get().alwaysApplyingWhenNonNull();
它的 SourceOperator 设置了一个
private static class NullPointerExceptionSafeSupplier<T> implements Supplier<T> {
private final Supplier<T> supplier;
NullPointerExceptionSafeSupplier(Supplier<T> supplier) {
this.supplier = supplier;
}
@Override
public T get() {
try {
return this.supplier.get();
}
catch (NullPointerException ex) {
return null;
}
}
}
由此,可以参考编写自己的校验逻辑。
end
此文档仅做一次技术点的使用,所以并没有过多讲解哈!