无法并行工作的自定义收集器

Joh*_*ier 3 java java-stream collectors

我制作了一个自定义收集器,它使用 MessageDigest 来创建哈希。一般来说,MessageDigest 不能并行工作。我看到的问题在于combiner()方法。无法组合两个 MessageDigest 对象。当我返回 null 时,它似乎可以工作,但如果我抛出一个,UnsupportedOperationException它就会失败。实现不支持并行操作的收集器的典型方法是什么?

class ChecksumCollector implements Collector<String, MessageDigest, ByteBuffer> {
    private String algorithm;

    ChecksumCollector(final String algorithm) {
        this.algorithm = algorithm;
    }

    @Override
    public Supplier<MessageDigest> supplier() {
        return () -> {
            try {
                return MessageDigest.getInstance(algorithm);
            } catch (NoSuchAlgorithmException e) {
                throw new UnsupportedOperationException("Could not find MessageDigest for algorithm " + algorithm, e);
            }
        };
    }

    @Override
    public BiConsumer<MessageDigest, String> accumulator() {
        return (md, s) -> md.update(s.getBytes(StandardCharsets.UTF_8));
    }

    @Override
    public BinaryOperator<MessageDigest> combiner() {
        return null; //seems to work but hash may not be correct?
        //throw new UnsupportedOperationException(LineDuplicationHash.class.getSimpleName() + " does not support parallel streams");
    }

    @Override
    public Function<MessageDigest, ByteBuffer> finisher() {
        return md -> ByteBuffer.wrap(md.digest());
    }

    @Override
    public Set<Characteristics> characteristics() {
        return Set.of();
    }
}
Run Code Online (Sandbox Code Playgroud)

Did*_*r L 5

返回的\ Collectorxe2\x80\x99s仅在用于并行流时使用,但是在 JDK\xe2\x80\x99s 实现中调用检索该组合器时将调用该方法本身(请参阅 参考资料)。BinaryOperatorcombiner()combiner()Stream.collect()ReduceOps.makeRef(Collector)

\n

因此你有两个选择:

\n
    \n
  • 要么 return nullNullPointerException如果您的收集器在并行流中使用,则需要使用组合器时,这会导致 a ;
  • \n
  • 或返回一个BinaryOperator在调用时实际抛出异常的:
  • \n
\n
return (a, b) -> throw new UnsupportedOperationException(\n    LineDuplicationHash.class.getSimpleName() + " does not support parallel streams");\n
Run Code Online (Sandbox Code Playgroud)\n

第二个选项对于不知情的开发人员来说会更友好,他们后来会更改管道以使其并行。

\n