当谈到Java时,我是相当的,我决定深入研究一下API的实现和使用,特别是流API。
我已经做了一个实现后,我认为我得到了正确的,它工作。然而,我意识到一些让我困扰的事情。
mapMulti函数接受参数aBiConsumer
:
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(理论上是mapper
参数)被认为是有效的,当它不是类型bicconsumer,并且只接受一个参数,即使当它在mapMulti内部调用时,它接受元素和缓冲区参数。
我可能完全错过了一些明显的东西,或者对这些函数有错误的理解,但我在理解BiConsumer, Consumer, Functions, BiFunctions
等方面遇到了一些麻烦。
提前感谢,我希望我能理解这类我觉得非常有趣的主题,特别是所有这些API的开发方式。
,如@Thomas Klager在评论中指出
Element.accept()是一个实例方法。要命名它,你需要两个对象:一个Element实例和一个Consumer消费者。方法引用足够聪明,可以将其检测为一个bicconsumerelement,消费者消费
elts.stream().<Integer>mapMulti((elt,cons)->{
elt.accept(cons);
})
和
elts.stream().<Integer>mapMulti(Element::accept)
是一样的
谢谢!