我是否需要自定义的Spliterator以避免额外的.stream()调用?

时间:2019-06-20 10:58:38

标签: java java-8 java-stream

我有这段代码可以正常工作,但是我发现它很难看。

@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

1 个答案:

答案 0 :(得分:4)

您可以使用简化的身份进行整理。一种方法可能是将mergeWith的实现更新为:

default ActionsBloc mergeWith(ActionsBloc ab) {
    this.actions().addAll(Optional.ofNullable(ab)
            .map(ActionsBloc::actions)
            .orElse(Collections.emptyList()));
    return this;
}

,然后将groupingreduction修改为:

this.blocs = new ArrayList<>(Stream.of(this.blocs, other.blocs)
        .flatMap(Collection::stream)
        .collect(groupingBy(ActionsBloc::getClass, reducing(null, ActionsBloc::mergeWith)))
        .values());

编辑:正如Holger指出的那样,进一步使用groupingBy来使用reducingtoMap这样的用例是:

this.blocs = new ArrayList<>(Stream.concat(this.blocs.stream(), other.blocs.stream())
        .collect(Collectors.toMap(ActionsBloc::getClass, Function.identity(), ActionsBloc::mergeWith))
        .values());