Java 获取迭代器的计数/长度/大小的最佳方法是什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9720195/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is the best way to get the count/length/size of an iterator?
提问by Zak
Is there a "computationally" quick way to get the count of an iterator?
是否有一种“计算上”快速的方法来获得迭代器的计数?
int i = 0;
for ( ; some_iterator.hasNext() ; ++i ) some_iterator.next();
... seems like a waste of CPU cycles.
...似乎浪费了 CPU 周期。
采纳答案by Michael Berry
If you've just got the iterator then that's what you'll have to do - it doesn't knowhow many items it's got left to iterate over, so you can't query it for that result. There are utility methods that will seem to do this (such as Iterators.size()
in Guava), but underneath they're just performing approximately the same operation.
如果您刚刚获得迭代器,那么这就是您必须做的 - 它不知道还剩下多少项可以迭代,因此您无法查询该结果。有一些实用方法似乎可以做到这一点(例如Iterators.size()
在 Guava 中),但在底层它们只是执行大致相同的操作。
However, many iterators come from collections, which you can often query for their size. And if it's a user made class you're getting the iterator for, you could look to provide a size() method on that class.
但是,许多迭代器来自集合,您通常可以查询它们的大小。如果它是一个用户创建的类,您正在为其获取迭代器,则可以考虑在该类上提供一个 size() 方法。
In short, in the situation where you onlyhave the iterator then there's no better way, but much more often than not you have access to the underlying collection or object from which you may be able to get the size directly.
简而言之,在只有迭代器的情况下,没有更好的方法,但通常情况下,您可以访问底层集合或对象,您可以从中直接获取大小。
回答by Stephen C
There is no more efficient way, if all you have is the iterator. And if the iterator can only be used once, then getting the count before you get the iterator's contents is ... problematic.
没有更有效的方法,如果你只有迭代器。如果迭代器只能使用一次,那么在获取迭代器内容之前获取计数是......有问题的。
The solution is either to change your application so that it doesn't need the count, or to obtain the count by some other means. (For example, pass a Collection
rather than Iterator
...)
解决方案是更改您的应用程序使其不需要计数,或者通过其他方式获取计数。(例如,传递一个Collection
而不是Iterator
...)
回答by assylias
Your code will give you an exception when you reach the end of the iterator. You could do:
当您到达迭代器的末尾时,您的代码会给您一个异常。你可以这样做:
int i = 0;
while(iterator.hasNext()) {
i++;
iterator.next();
}
If you had access to the underlying collection, you would be able to call coll.size()
...
如果您有权访问基础集合,则可以调用coll.size()
...
EDITOK you have amended...
编辑好的,你已经修改了...
回答by Chandra Sekhar
iterator object contains the same number of elements what your collection contained.
迭代器对象包含的元素数量与您的集合所包含的元素数量相同。
List<E> a =...;
Iterator<E> i = a.iterator();
int size = a.size();//Because iterators size is equal to list a's size.
But instead of getting the size of iterator and iterating through index 0 to that size, it is better to iterate through the method next()of the iterator.
但是与其获取迭代器的大小并通过索引 0 迭代到该大小,不如迭代迭代器的next()方法。
回答by Roger Lindsj?
If all you have is the iterator, then no, there is no "better" way. If the iterator comes from a collection you could as that for size.
如果您拥有的只是迭代器,那么不,没有“更好”的方法。如果迭代器来自一个集合,你可以作为大小。
Keep in mind that Iterator is just an interface for traversing distinct values, you would very well have code such as this
请记住,迭代器只是一个用于遍历不同值的接口,您很可能会拥有这样的代码
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");
}
};
or
或者
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");
}
};
回答by Andrejs
Using Guava library:
使用番石榴库:
int size = Iterators.size(iterator);
Internally it just iterates over all elements so its just for convenience.
在内部,它只是迭代所有元素,因此只是为了方便。
回答by tashuhka
Using Guava library, another option is to convert the Iterable
to a List
.
使用番石榴库,另一种选择是将转换Iterable
为List
。
List list = Lists.newArrayList(some_iterator);
int count = list.size();
Use this if you need also to access the elements of the iterator after getting its size. By using Iterators.size()
you no longer can access the iterated elements.
如果您还需要在获取其大小后访问迭代器的元素,请使用此选项。通过使用Iterators.size()
您不再可以访问迭代元素。
回答by gil.fernandes
You will always have to iterate. Yet you can use Java 8, 9 to do the counting without looping explicitely:
您将始终必须迭代。然而,您可以使用 Java 8、9 进行计数而无需显式循环:
Iterable<Integer> newIterable = () -> iter;
long count = StreamSupport.stream(newIterable.spliterator(), false).count();
Here is a test:
这是一个测试:
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);
}
This prints:
这打印:
5
Interesting enough you can parallelize the count operation here by changing the parallel
flag on this call:
有趣的是,您可以通过更改parallel
此调用中的标志来并行化计数操作:
long count = StreamSupport.stream(newIterable.spliterator(), *true*).count();
回答by robbie70
for Java 8you could use,
对于Java 8,您可以使用,
public static int getIteratorSize(Iterator iterator){
AtomicInteger count = new AtomicInteger(0);
iterator.forEachRemaining(element -> {
count.incrementAndGet();
});
return count.get();
}