【问题标题】:Testing the 4th object of an iterator - Java测试迭代器的第四个对象 - Java
【发布时间】:2018-11-04 17:06:45
【问题描述】:

是否可以在迭代器中断言第 4 个对象的 only 值?

我已经看到人们使用迭代器循环列表的示例,但我不想将索引0 中保存的对象取出到2,而只是索引3 中的对象...

我知道我总是可以做到.next().next().next(),但这看起来有点……傻。有什么方法可以让我直接做.next(4) 之类的事情吗?

【问题讨论】:

  • 不,它不可能的迭代器没有被创建以允许直接访问。
  • 您可以实现自己的迭代器,它具有此功能。但在你的情况下,我不会使用 itearator。
  • 感谢您的信息。我没有经常使用迭代器,所以我知道的越多:-)
  • 为什么不只是if(list.size()>3) { list.get(3); }

标签: java list iterator


【解决方案1】:

迭代器不适用于索引,它们不知道最后一项出现在哪个索引处。它们的唯一目的是遍历元素直到到达终点。

这意味着,如果你想使用第 4 个元素,你必须调用 Iterator::next() 四次。可能会发生迭代器中只有 3 个或更少元素的情况,因此您必须检查 Iterator::hasNext(),否则当没有更多元素并且您再次调用 next() 时,会抛出 NoSuchElementException


另外,从 Java-8 开始,您可以使用 Iterator::forEachRemaining(Consumer<? super E> action) 方法,该方法对剩余的每个元素执行给定的操作。此外,您需要对数组使用技巧来避免 lambda 表达式中的 effectively final 变量约束。遗憾的是,此方法不接受 BiConsumer<T,U> 作为参数来消耗元素和索引 - 这就是这个技巧的原因。

List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
int index[] = new int[]{0};

// Prints 4 and 8
Iterator<Integer> iterator = list.iterator();
iterator.forEachRemaining(i -> {
    if ((index[0]+1)%4 == 0) {
        // Here you work both with the element `i` and its index `index[0]`
        System.out.println(i);     
    }
    index[0]++;
});

【讨论】:

    【解决方案2】:

    使用番石榴Iterators

    Guava 对此提议有一个通用的实用程序类。这个术语的确切答案是:

    在此示例中,如果提供的position 是超出其边界 的高级迭代器,则可能会遇到IndexOutOfBoundsException

    @Test
    public void getNthElement() {
        List<String> alphabet = Arrays.asList("a", "b", "c", "d");
        Iterator<String> iterator = alphabet.iterator();
    
        int position = 3;
        String forthElement = Iterators.get(iterator, 3);
    
        assertEquals("d", forthElement);
    }
    

    Iteratorsget(Iterator&lt;T&gt;, int) 方法提供了方便的重载,因此您永远不会得到IndexOutOfBoundsException

    @Test
    public void getNthElementWithDefaultValue() {
        List<String> alphabet = Arrays.asList("a", "b", "c", "d");
        Iterator<String> iterator = alphabet.iterator();
        int position = 10;
        final String actual = Iterators.get(iterator, position, "default");
    
        assertEquals("default", actual);
    }
    

    如果有必要跳过或到达特定位置,但这里是@Nikolas 提到的案例。在这里您可以轻松获取NoSuchElementException

    @Test
    public void advance() {
        List<String> alphabet = Arrays.asList("a", "b", "c", "d", "e", "f");
        Iterator<String> iterator = alphabet.iterator();
    
        // will return the number of skipped elements
        int advance = Iterators.advance(iterator, 3);
    
        assertEquals(3, advance);
        assertEquals("d", iterator.next());
    }
    
    @Test(expected = NoSuchElementException.class)
    public void advanceBeyond() {
        List<String> alphabet = Arrays.asList("a", "b", "c");
        Iterator<String> iterator = alphabet.iterator();
    
        int advance = Iterators.advance(iterator, 3);
    
        // throws the exception because we advanced iterator to end
        iterator.next();
    }
    

    如果你不能或不想依赖 Guava

    这是到达迭代器位置的非常简单(教育)的实现。

    public static <T> T get(Iterator<T> iterator, int pos) {
        if (pos < 0) {
            throw new IllegalArgumentException("Position is negative!");
        }
    
        int i = 0;
    
        while (i++ < pos) {
            iterator.next();
        }
    
        return iterator.next();
    }
    

    【讨论】:

      【解决方案3】:

      如果你不局限于迭代器,你可以使用 Java 8 Streams 来做类似的事情:

      Object opt = collection.stream().skip(3).findFirst().orElse(null);
      //opt will be null if there were 3 or fewer items in the collection
      if(opt!=null) {}
      
      //or to operate on the rest of the Stream
      collection.stream().skip(3).forEach(...)
      

      【讨论】:

        【解决方案4】:

        您可以使用AssertJ 简洁地断言:

        Iterator<Integer> it = List.of(2, 4, 6, 8, 10).iterator();
        
        assertThat(it).element(3).isEqualTo(8);
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2013-07-03
          • 2013-04-12
          • 2020-02-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-10-05
          相关资源
          最近更新 更多