假设我有一些Java实体的清单,例如
List<Entity> entities = Arrays.asList(entity1, entity2, entity3...);
我想将其简化为链对象的一个实例,例如:
class EntityChain {
private final Entity entity;
private final Optional<EntityChain> fallback;
private EntityChain(Builder builder) {
this.entity = builder.entity;
this.fallback = builder.fallback;
}
public static Builder builder() {
return new Builder();
}
public static final class Builder {
private Entity entity;
private Optional<EntityChain> fallback = Optional.empty();
public Builder withEntity(Entity entity) {
this.entity = entity;
return this;
}
public Builder withFallback(EntityChain fallback) {
this.fallback = Optional.of(fallback);
return this;
}
public EntityChain build() {
return new EntityChain(this);
}
}
}
EntityChain
是不可变的,并且具有生成器。这样结果将是一个
EntityChain
实例,例如:chain
-> entity = entity1
-> fallback
-> entity = entity2
-> fallback
-> entity = entity3
-> fallback
...
是否可以通过一些神奇的Java 8流利度降低来做到这一点?
是
Stream.reduce(U identity,
BiFunction<U, ? super T, U> accumulator,
BinaryOperator<U> combiner)
在这里适用吗?使用某种方式是建设者?
最佳答案
经过思考,我发现在按顺序减少流时可以完全删除持有人Supplier<EntityChain>
。该算法是建立反向的实体链:首先建立entity(n),然后建立entity(n-1),再建立entity(0)。
BiFunction<EntityChain, Entity, EntityChain> reducing =
(next, entity) -> Optional.ofNullable(next)
// create a builder with fallback if EntityChain present
.map(fallback -> EntityChain.builder().withFallback(fallback))
// create a builder without fallback
.orElseGet(EntityChain::builder)
//build the EntityChain
.withEntity(entity).build();
// combiner never be used in sequentially stream
BinaryOperator<EntityChain> rejectedInParallelStream = (t1, t2) -> {
//when you use parallel the chain order maybe changed, and the result is wrong.
throw new IllegalStateException("Can't be used in parallel stream!");
};
EntityChain chain = reverse(entities).
stream().reduce(null, reducing, rejectedInParallelStream);
//copy & reverse the copied List
static <T> List<T> reverse(List<T> list) {
List<T> it = list.stream().collect(Collectors.toList());
Collections.reverse(it);
return it;
}
输出量
-> entity = entity1
-> fallback
-> entity = entity2
-> fallback (empty)