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或任何其他方式来确定迭代器是否实际上是原始的.我已经搜索了很长一段时间,但通常只是浏览几乎所有问题的答案,这次我不得不在这里注册直接问这个问题.
这种结构旨在避免装箱/拆箱狂欢,因为我希望新的迭代器速度相当快.
所以这里有三个问题:
更新:由于霍尔格斯回答,它归结为以下问题nr.4:如果next()在a上PrimitiveInteger.OfInt调用,则会调用该nextInt()方法,换句话说:这会自动返回纯粹的int吗?或者它仍然会导致拳击和拆箱序列?
从下面的答案我假设后者,这意味着明确地处理它肯定更好nextInt().
假设这是正确的(请告诉我,如果我错了),我使用了instanceof下面的方法并在需要时明确换行.
好吧,您可以简单地使用iterator instanceof PrimitiveIterator.OfIntto 进行测试,但是当预期的操作是 时forEachRemaining,您将需要将两个IntConsumer传递给 进行PrimitiveIterator.OfInt高效处理,并使用 aConsumer<Integer>来处理不是 的实例的迭代器PrimitiveIterator.OfInt,如果您在一个类中实现这两个迭代器,你根本不需要执行测试,迭代器会为你做:
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}\nRun Code Online (Sandbox Code Playgroud)\npublic 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}\nRun 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
这不适用于通过hasNext()/进行的单元素处理next(),但由于您的代码应该PrimitiveIterable.OfInt仅执行组合,因此初始步骤是唯一必须进行调整的地方
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}\nRun Code Online (Sandbox Code Playgroud)\n创建此方法一次后,您可以在所有接受 的地方使用它Iterable,例如
public static FilterIteratorInt filter(Iterable<Integer> iter, IntPredicate filter) {\n return new FilterIteratorInt(adapt(iter.iterator()), filter);\n}\nRun Code Online (Sandbox Code Playgroud)\n但请注意,这个 \xe2\x80\x9citerator 组合 \xe2\x80\x9d 看起来非常像 Stream API(或IntStream具体的 API)\xe2\x80\xa6 的重新发明
| 归档时间: |
|
| 查看次数: |
147 次 |
| 最近记录: |