0

在谈到 Java 时,我是公平的,我决定深入研究 API 的实现和使用,尤其是 Stream API。

在认为我做对了之后,我做了一个实现,并且它奏效了。然而,我意识到了一些让我烦恼的事情。

mapMulti 函数接受参数 a BiConsumer

    default <R> Stream<R> mapMulti(BiConsumer<? super T, ? super Consumer<R>> mapper) {
        Objects.requireNonNull(mapper);
        return flatMap(e -> {
            SpinedBuffer<R> buffer = new SpinedBuffer<>();
            mapper.accept(e, buffer);
            return StreamSupport.stream(buffer.spliterator(), false);
        });
    }

然后我想通过将我的 Element 类的接受函数传递给 mapMulti 函数来对它进行基准测试(这就是为什么我丢弃 的值s,而 ExecutionPlan 只是具有与 JMH 进行基准测试的值

    public void mapMultiTest(ExecutionPlan exec){
        Stream<Integer> s = exec.elts.stream().mapMulti(Element::accept);
    }

这是 Element 类,它简单地将 int 分解为素数,并在消费者上调用 forEach。

public record Element(int value) {

    public void accept(Consumer<Integer> consumer) {
        decomp().forEach(consumer);
    }

    public ArrayList<Integer> decomp() {
        ArrayList<Integer> list = new ArrayList<>();
        int value = this.value;

        while (!isPrime(value)) {
            int prime = 2;
            while (!isPrime(prime) || value % prime != 0)
                prime++;
            list.add(prime);
            value /= prime;
        }
        list.add(value);
        return list;
    }

    private boolean isPrime(int num) {
        if (num <= 1) {
            return false;
        }
        for (int i = 2; i <= Math.sqrt(num); i++) {
            if (num % i == 0) {
                return false;
            }
        }
        return true;
    }
}

我的问题是:为什么我的 Element::accept (理论上是mapperarg)在不是 BiConsumer 类型时被认为是有效的,并且只接受一个参数,即使在 mapMulti 内部调用它时,它也接受元素和缓冲区争论。

我可能完全遗漏了一些明显的东西或对这些功能有错误的理解,但我在理解BiConsumer, Consumer, Functions, BiFunctions等方面遇到了一些麻烦。

在此先感谢,我希望我能理解我觉得非常有趣的这类主题,尤其是所有这些 API 的开发方式。

4

1 回答 1

1

所以,正如@Thomas Kläger在评论中指出的那样

Element.accept() 是一个实例方法。要调用它,您需要两个对象:一个 Element 实例和一个 Consumer 消费者。方法引用足够聪明,可以将其检测为 BiConsumer<Element, Consumer consumer

所以

elts.stream().<Integer>mapMulti((elt,cons)->{
            elt.accept(cons);
        })

elts.stream().<Integer>mapMulti(Element::accept)

是一样的吗

非常感谢 !

于 2021-09-03T11:57:45.640 回答