我有这段代码可以正常工作,但是我发现它很难看。
@EqualsAndHashCode
public abstract class Actions {
@Getter
private List<ActionsBloc> blocs;
public Actions mergeWith(@NotNull Actions other) {
this.blocs = Stream.of(this.blocs, other.blocs)
.flatMap(Collection::stream)
.collect(groupingBy(ActionsBloc::getClass, reducing(ActionsBloc::mergeWith)))
.values()
.stream()
.filter(Optional::isPresent)
.map(Optional::get)
.collect(toList());
return this;
}
}
ActionsBloc
是一个超级类型,其中包含Action
的列表。
public interface ActionsBloc {
<T extends Action> List<T> actions();
default ActionsBloc mergeWith(ActionsBloc ab) {
this.actions().addAll(ab.actions());
return this;
}
}
我想要做的是基于blocs
类型将Actions
中的Class
合并在一起。因此,我将按ActionsBloc::getClass
分组,然后通过调用ActionsBloc::mergeWith
进行合并。
在第一个流在values().stream()
上结束后,我发现丑陋的叫collect
。
是否有一种方法只能对一个流进行操作并摆脱values().stream()
,还是必须编写自定义的Spliterator?换句话说,我的代码中只有一个collect
。
答案 0 :(得分:4)
您可以使用简化的身份进行整理。一种方法可能是将mergeWith
的实现更新为:
default ActionsBloc mergeWith(ActionsBloc ab) {
this.actions().addAll(Optional.ofNullable(ab)
.map(ActionsBloc::actions)
.orElse(Collections.emptyList()));
return this;
}
,然后将grouping
和reduction
修改为:
this.blocs = new ArrayList<>(Stream.of(this.blocs, other.blocs)
.flatMap(Collection::stream)
.collect(groupingBy(ActionsBloc::getClass, reducing(null, ActionsBloc::mergeWith)))
.values());
编辑:正如Holger指出的那样,进一步使用groupingBy
来使用reducing
和toMap
这样的用例是:
this.blocs = new ArrayList<>(Stream.concat(this.blocs.stream(), other.blocs.stream())
.collect(Collectors.toMap(ActionsBloc::getClass, Function.identity(), ActionsBloc::mergeWith))
.values());