Java 8中的方法是否可以简单地确定Iterable <Integer> Object是否提供了PrimitiveIterator.OfInt迭代器?

Blo*_*uth 5 iterator iterable java-8

这是我在这里的第一个活动,我希望我的行为正确!我的问题:我试图写一个函数集合(一类的静态方法)接受一个或多个Iterable<Integer>并获得primitiveIterator.ofInt,它提供了对构造另一个迭代器(另一种功能,即功能是为了撰写迭代器以各种方式).

这是我想到的一个简单例子:

public static FilterIteratorInt filtor(Iterable<Integer> iter, IntPredicate filter)
{
    return new FilterIteratorInt((PrimitiveIterator.OfInt)iter.iterator(),filter);
}   
Run Code Online (Sandbox Code Playgroud)

对我而言,目前尚不清楚这是否可行,因为Object iterator返回的内容Iterable<Integer>可能不是类型PrimitiveIterator.OfInt.

为了克服这个潜在的困难,我一直在寻找一个解决方案,它可能是一个接口,例如PrimitiveIterable.OfInt或任何其他方式来确定迭代器是否实际上是原始的.我已经搜索了很长一段时间,但通常只是浏览几乎所有问题的答案,这次我不得不在这里注册直接问这个问题.

这种结构旨在避免装箱/拆箱狂欢,因为我希望新的迭代器速度相当快.

所以这里有三个问题:

  1. 有没有办法找出从迭代中获得的迭代器实际上是一个原始迭代器(这样函数可以区分并相应地行动)还是有另一种方法来获得一个?
  2. 尝试以这种方式提高性能可能毫无用处吗?即,(JIT或Java)编译器无论如何都会对此进行优化,或者无论如何都是不可避免的装箱/拆箱?在这里,我希望学到一些东西.
  3. 有人可以向我展示一个可以用于相同目的的不同且更好的解决方案(即原始迭代器的组合,或任何迭代器的组合,而我们在其中)?

更新:由于霍尔格斯回答,它归结为以下问题nr.4:如果next()在a上PrimitiveInteger.OfInt调用,则会调用该nextInt()方法,换句话说:这会自动返回纯粹的int吗?或者它仍然会导致拳击和拆箱序列?

从下面的答案我假设后者,这意味着明确地处理它肯定更好nextInt().

假设这是正确的(请告诉我,如果我错了),我使用了instanceof下面的方法并在需要时明确换行.

Hol*_*ger 4

好吧,您可以简单地使用iterator instanceof PrimitiveIterator.OfIntto 进行测试,但是当预期的操作是 时forEachRemaining,您将需要将两个IntConsumer传递给 进行PrimitiveIterator.OfInt高效处理,并使用 aConsumer<Integer>来处理不是 的实例的迭代器PrimitiveIterator.OfInt,如果您在一个类中实现这两个迭代器,你根本不需要执行测试,迭代器会为你做:

\n
public static void main(String[] args) {\n    System.out.println("with Collection (of Integer boxes)");\n    filterAndPrint(Arrays.asList(1, 2, 3), i -> i>2);\n    System.out.println("with IntStream (using primitive int values)");\n    filterAndPrint(() -> IntStream.range(1, 4).iterator(), i -> i>2);\n}\ninterface LoggingUnboxingIntConsumer extends IntConsumer, Consumer<Integer> {\n    @Override default void accept(Integer t) {\n        System.out.println("  unboxing " + t);\n            accept(t.intValue());\n    }\n}\npublic static void filterAndPrint(Iterable<Integer> i, IntPredicate p) {\n    i.iterator().forEachRemaining((LoggingUnboxingIntConsumer) (int value) -> {\n        if(p.test(value)) System.out.println("  value "+value+" matches");\n    });\n}\n
Run Code Online (Sandbox Code Playgroud)\n
public static void main(String[] args) {\n    System.out.println("with Collection (of Integer boxes)");\n    filterAndPrint(Arrays.asList(1, 2, 3), i -> i>2);\n    System.out.println("with IntStream (using primitive int values)");\n    filterAndPrint(() -> IntStream.range(1, 4).iterator(), i -> i>2);\n}\ninterface LoggingUnboxingIntConsumer extends IntConsumer, Consumer<Integer> {\n    @Override default void accept(Integer t) {\n        System.out.println("  unboxing " + t);\n            accept(t.intValue());\n    }\n}\npublic static void filterAndPrint(Iterable<Integer> i, IntPredicate p) {\n    i.iterator().forEachRemaining((LoggingUnboxingIntConsumer) (int value) -> {\n        if(p.test(value)) System.out.println("  value "+value+" matches");\n    });\n}\n
Run Code Online (Sandbox Code Playgroud)\n

这表明尽可能避免装箱操作。这是合同的PrimitiveIterator.OfInt.forEachRemaining(Consumer<? super Integer>)一部分:

\n
\n

实施要求:

\n

如果操作是 IntConsumer 的实例,则将其强制转换为 IntConsumer 并传递给 forEachRemaining(java.util.function.IntConsumer); 否则,通过装箱 IntConsumer 的参数,将操作适应 IntConsumer 的实例,然后传递给 forEachRemaining(java.util.function.IntConsumer)。

\n
\n

这不适用于通过hasNext()/进行的单元素处理next(),但由于您的代码应该PrimitiveIterable.OfInt仅执行组合,因此初始步骤是唯一必须进行调整的地方

\n
public static PrimitiveIterator.OfInt adapt(Iterator<Integer> it) {\n    return it instanceof PrimitiveIterator.OfInt? (PrimitiveIterator.OfInt)it:\n      new PrimitiveIterator.OfInt() {\n        public int nextInt() { return it.next(); }\n        public boolean hasNext() { return it.hasNext(); }\n        public Integer next() { return it.next(); }\n      };\n}\n
Run Code Online (Sandbox Code Playgroud)\n

创建此方法一次后,您可以在所有接受 的地方使用它Iterable,例如

\n
public static FilterIteratorInt filter(Iterable<Integer> iter, IntPredicate filter) {\n    return new FilterIteratorInt(adapt(iter.iterator()), filter);\n}\n
Run Code Online (Sandbox Code Playgroud)\n

但请注意,这个 \xe2\x80\x9citerator 组合 \xe2\x80\x9d 看起来非常像 Stream API(或IntStream具体的 API)\xe2\x80\xa6 的重新发明

\n