获得迭代器的数量/长度/大小的最佳方式是什么?
是否有一种“计算上”的快速方法来获得迭代器的计数?获得迭代器的数量/长度/大小的最佳方式是什么?
int i = 0;
for (; some_iterator.hasNext() ; ++i) some_iterator.next();
...似乎是浪费CPU周期。
如果你拿到的迭代器那么这是你必须做的 - 它不知道它有多少项目就剩到迭代,所以你不能查询它的结果。
但是,许多迭代器来自集合,您可以经常查询它们的大小。如果它是一个用户创建的类,您将获得迭代器,您可以在该类上提供size()方法。
简而言之,在只有有迭代器的情况下,没有更好的方法,但更多的情况是您可以访问底层集合或对象,从中可以直接获取大小。
没有更有效的方法,如果你拥有的只是迭代器。如果迭代器只能使用一次,那么在获取迭代器的内容之前获取计数是有问题的。
解决方案是更改您的应用程序,使其不需要计数或通过其他方式获取计数。 (例如,通过一个Collection
而非Iterator
...)
当你到达迭代器的末尾时,你的代码会给你一个异常。你可以这样做:
int i = 0;
while(iterator.hasNext()) {
i++;
iterator.next();
}
如果你有机会访问底层集合,你就可以打电话coll.size()
......
编辑 确定你已经修改了...
迭代器对象包含与您的集合包含的元素相同数量的元素。
List<E> a =...;
Iterator<E> i = a.iterator();
int size = a.size();//Because iterators size is equal to list a's size.
而是获得迭代器的尺寸,并通过索引0迭代到规定大小,最好是通过该方法的迭代器的下()进行迭代。
如果我们没有'a',但只有'i',该怎么办? – Tvde1 2017-09-25 08:47:52
如果你拥有的只是迭代器,那么不,没有“更好”的方法。如果迭代器来自一个集合,那么可以按照大小进行设置。
请记住,迭代器就是为穿越不同值的界面,你会很好得如下代码
new Iterator<Long>() {
final Random r = new Random();
@Override
public boolean hasNext() {
return true;
}
@Override
public Long next() {
return r.nextLong();
}
@Override
public void remove() {
throw new IllegalArgumentException("Not implemented");
}
};
或
new Iterator<BigInteger>() {
BigInteger next = BigInteger.ZERO;
@Override
public boolean hasNext() {
return true;
}
@Override
public BigInteger next() {
BigInteger current = next;
next = next.add(BigInteger.ONE);
return current;
}
@Override
public void remove() {
throw new IllegalArgumentException("Not implemented");
}
};
另一种选择是将Iterable
转换为List
。
int count = Lists.newArrayList(some_iterator).size();
它有多少效率? – LoveToCode 2016-04-27 12:55:48
@LoveToCode比原始问题上的例子效率低 – Winter 2016-12-20 17:44:41
当然,创建一个包含所有元素的新对象比迭代和丢弃要慢。恕我直言,这个解决方案是一个提高代码可读性的单线程。我使用它很多元素(高达1000)或速度不是问题的集合。 – tashuhka 2016-12-21 10:05:23
您将始终需要迭代。然而,你可以使用Java 8,9做计数没有明确地循环:
Iterable<Integer> newIterable =() -> iter;
long count = StreamSupport.stream(newIterable.spliterator(), false).count();
下面是测试:
public static void main(String[] args) throws IOException {
Iterator<Integer> iter = Arrays.asList(1, 2, 3, 4, 5).iterator();
Iterable<Integer> newIterable =() -> iter;
long count = StreamSupport.stream(newIterable.spliterator(), false).count();
System.out.println(count);
}
此打印:
5
足够有趣,你可以并行通过更改此通话中的parallel
标志来计数操作:
long count = StreamSupport.stream(newIterable.spliterator(), *true*).count();
迭代器不一定对应于具有“count”的东西... – 2012-03-15 13:01:05
迭代器是它们是什么;迭代到集合中的下一个对象(它可以是set,array等任何东西)为什么当他们不关心他们想要迭代的内容时,他们需要告诉大小? '为访问提供独立于实现的方法,其中用户不需要知道底层实现是某种形式的数组还是链接列表,并且允许用户在没有明确索引的情况下浏览集合。 /penguin.ewu.edu/~trolfe/LinkedSort/Iterator.html – ecle 2012-03-15 13:01:42