[英]Testing the 4th object of an iterator - Java
是否可以在迭代器中声明第4个对象的唯一值?
我见过人们用迭代器遍历列表的示例,但是我不想弄清楚索引0
到2
保存的对象,而只是索引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(...)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.