Java 8中原始专业化的不一致性

时间:2016-10-23 22:20:38

标签: java collections primitive

为什么PrimitiveIterator.OfInt延伸Iterator<Integer>IntStream不延伸Stream<Integer>

我正在尝试设计一个原始集合类型(类似于Apache Commons Primitives库(http://commons.apache.org/dormant/commons-primitives/)中的接口,并尝试与集合库保持一致和兼容,但我无法决定我是否应该ByteList延长List<Byte>

我的猜测是因为Iterator在语言中有直接语法支持(即对于使用迭代器的循环)所以尽管它强制装箱,但是值得使迭代器与该语法兼容,但我很好奇如果有人知道是否有更深层次的原因。谢谢!

1 个答案:

答案 0 :(得分:1)

很难说出为什么JDK API的设计方式与它们的设计方式相同,但在这种情况下,我们可以很容易地看到尝试使Stream<Integer>IntStream的API协同工作很难做到,因为两个接口的方法定义都存在许多含糊之处。

请考虑以下事项:

interface Stream<T> {
    Stream<T> distinct();
    Optional<T> findFirst();
}

interface IntStream extends Stream<Integer> {
    IntStream distinct();
    OptionalInt findFirst();
}

第二个接口不会进行事件编译,因为方法的签名是相同的,但返回类型在第二个接口中是不同的。

当我们提供接受lambdas的相同方法的多个实现时,即使是兼容的方法也可能变得难以使用。 Lambda和方法的重载通常不能很好地一起使用,因为给定的lambda可以实现多个功能接口。例如:

interface Stream<T> {
    Stream<T> filter(Predicate<T> p);
    <S> Stream<S> map(Function<T,S> mapper);
}

interface IntStream extends Stream<Integer> {
    IntStream filter(IntPredicate p);
    IntStream map(IntUnaryOperator mapper);
}

现在,如果你有一个像stream.filter(n -> n > 10)这样的调用,这个lambda实际上可以实现Predicate<Integer>IntPredicate,现在API用户被迫做某种消歧,例如(int n) -> n > 10,因为编译器无法区分。

我认为,从长远来看,这可能会阻碍StreamIntStream API的发展。