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

标签 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 是一个父类(super class)型,其中包含 Action 列表。

public interface ActionsBloc {

    <T extends Action> List<T> actions();

    default ActionsBloc mergeWith(ActionsBloc ab) {
        this.actions().addAll(ab.actions());
        return this;
    }
}

我想要做的是根据Class类型将Actionsblocs合并在一起。因此,我按 ActionsBloc::getClass 进行分组,然后通过调用 ActionsBloc::mergeWith 进行合并。

我觉得丑陋的是在collect上第一个流结束后调用values().stream()

有没有一种方法可以只对一个流进行操作并摆脱 values().stream(),或者我是否必须编写一个自定义 Spliterator?换句话说,我的代码中只有一个 collect

最佳答案

您可以使用简化的身份来解决这个问题。一种方法是将 mergeWith 的实现更新为:

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

然后将分组缩减修改为:

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

编辑:正如 Holger 指出的那样,使用 groupingByreducing 进一步使用 toMap< 可以更合适地实现为:

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

关于java - 我是否需要自定义 Spliterator 来避免额外的 .stream() 调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56684523/

相关文章:

java - log4j.xml 配置仅用于调试

java - 多个 'or' 语句导致 boolean 方法始终返回 true。为什么?

java - 启动 swing 应用程序的最佳实践

java - 使用函数式接口(interface) (lambda) 从 POJO 列表中收集值

java - 使用 Java 8 流对多个变量列表进行排序

java - 使用流 API 将数组的 HashMap 组合成数组

java - 在java中使用stream api的复杂操作

java - 从非静态字段更改静态引用?

java - 我应该流多次还是在一个流中进行所有计算?

java-8 - 以微秒为单位获取持续时间