繁体   English   中英

测试迭代器的第4个对象-Java

[英]Testing the 4th object of an iterator - Java

是否可以在迭代器中声明第4个对象的唯一值?

我见过人们用迭代器遍历列表的示例,但是我不想弄清楚索引02保存的对象,而只是索引3 ...

我知道我总是可以做.next().next().next() ,但这看起来有点...很傻。 有什么办法可以使像.next(4)一样直接进行?

迭代器不适用于索引,并且他们不知道最后一项显示在什么索引上。 它们的唯一目的是遍历元素直到结束。

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


另外,从Java-8开始,您可以使用Iterator::forEachRemaining(Consumer<? super E> action) ,该方法为其余每个元素执行给定操作。 另外,您需要对数组使用技巧,以避免在lambda表达式内有效地限制最终变量。 可悲的是,此方法不接受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]++;
});

使用番石榴迭代器

番石榴对此有一个通用的实用程序类。 用这个术语的确切答案将是:

. 在此示例中,如果提供的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);
}

迭代器get(Iterator<T>, 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();
}

如果您不能或不想依靠番石榴

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

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();
}

如果不限于迭代器,则可以使用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(...)

您可以使用AssertJ明确声明这一点:

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

assertThat(it).element(3).isEqualTo(8);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM