Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/347.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 获取迭代器的计数/长度/大小的最佳方法是什么?_Java_Iterator - Fatal编程技术网

Java 获取迭代器的计数/长度/大小的最佳方法是什么?

Java 获取迭代器的计数/长度/大小的最佳方法是什么?,java,iterator,Java,Iterator,是否有一种“计算”的快速方法来获取迭代器的计数 int i = 0; for ( ; some_iterator.hasNext() ; ++i ) some_iterator.next(); 。。。似乎是在浪费CPU周期。如果您只有迭代器,那么就没有更有效的方法了。如果迭代器只能使用一次,那么在获取迭代器内容之前获取计数是。。。有问题 解决方案是更改应用程序,使其不需要计数,或者通过其他方法获得计数。(例如,传递一个集合而不是迭代器…)如果您刚刚得到迭代器,那么这就是您必须做的-它不知道还有

是否有一种“计算”的快速方法来获取迭代器的计数

int i = 0;
for ( ; some_iterator.hasNext() ; ++i ) some_iterator.next();

。。。似乎是在浪费CPU周期。

如果您只有迭代器,那么就没有更有效的方法了。如果迭代器只能使用一次,那么在获取迭代器内容之前获取计数是。。。有问题


解决方案是更改应用程序,使其不需要计数,或者通过其他方法获得计数。(例如,传递一个
集合
而不是
迭代器
…)

如果您刚刚得到迭代器,那么这就是您必须做的-它不知道还有多少项需要迭代,因此您无法查询该结果。有一些实用方法似乎可以有效地做到这一点(如Guava中的
Iterators.size()
),但在其下面,它们只是使用迭代器并在运行时计数,与您的示例中相同

然而,许多迭代器来自集合,您通常可以查询集合的大小。如果它是一个用户创建的类,您可以为其获取迭代器,您可以在该类上提供size()方法


简言之,在只有迭代器的情况下,没有更好的方法,但通常情况下,您可以访问底层集合或对象,从中可以直接获得大小。

当到达迭代器的末尾时,代码会给您一个异常。你可以做:

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.
列表a=。。。;
迭代器i=a.迭代器();
int size=a.size()//因为迭代器的大小等于列表a的大小。

但与其获得迭代器的大小并通过索引0迭代到该大小,不如通过迭代器的方法next()进行迭代。

如果您只有迭代器,那么没有更好的方法。如果迭代器来自一个集合,您可以将其作为大小

请记住,迭代器只是一个用于遍历不同值的接口,您很可能会有这样的代码

    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");
        }
    };
新迭代器(){
最终随机r=新随机();
@凌驾
公共布尔hasNext(){
返回true;
}
@凌驾
公共长廊(下){
返回r.nextLong();
}
@凌驾
公共空间删除(){
抛出新的IllegalArgumentException(“未实现”);
}
};

新迭代器(){
biginger next=biginger.ZERO;
@凌驾
公共布尔hasNext(){
返回true;
}
@凌驾
公共biginger next(){
BigInteger当前=下一个;
next=next.add(biginger.ONE);
回流;
}
@凌驾
公共空间删除(){
抛出新的IllegalArgumentException(“未实现”);
}
}; 
使用:

在内部,它只是对所有元素进行迭代,因此只是为了方便。

使用,另一个选项是将
Iterable
转换为
列表

List list = Lists.newArrayList(some_iterator);
int count = list.size();

如果在获得迭代器的大小后还需要访问迭代器的元素,请使用此选项。通过使用迭代器.size()
您将无法再访问迭代的元素。

您将始终必须进行迭代。但是,您可以使用Java 8、9进行计数,而无需显式循环:

Iterable<Integer> newIterable = () -> iter;
long count = StreamSupport.stream(newIterable.spliterator(), false).count();
有趣的是,通过更改此调用上的
parallel
标志,您可以在此处并行化计数操作:

long count = StreamSupport.stream(newIterable.spliterator(), *true*).count();

对于Java8,您可以使用

public static int getIteratorSize(Iterator iterator){
        AtomicInteger count = new AtomicInteger(0);
        iterator.forEachRemaining(element -> {
            count.incrementAndGet();
        });
        return count.get();
    }

迭代器不一定与具有“计数”的事物对应……迭代器就是它们;要迭代到集合的下一个对象(可以是集合、数组等任何对象),当他们不关心迭代的目的是什么时,为什么需要告诉大小
提供一种独立于实现的访问方法,在这种方法中,用户不需要知道底层实现是某种形式的数组还是链表,并允许用户在没有显式索引的情况下遍历集合。
@LoveToCode效率低于原始问题的示例Sure,创建一个包含所有元素的新对象比仅仅迭代和丢弃要慢。依我看,这个解决方案是一个提高代码可读性的单行程序。我经常使用它来收集一些元素(最多1000个),或者当速度不是问题时。如果我们没有
a
,但只有
I
,会怎么样?这非常优雅。请记住,您正在使用迭代器(即,迭代器随后将为空)。这不是“计算速度快”,这是一种方便的方法,具有使用迭代器的不希望的副作用。您能解释一下这是如何工作的吗@Andrejs List wordCountsWithGroupByKey=wordspairdd.groupByKey().mapValues(intIterable->Iterables.size(intIterable)).collect();System.out.println(“wordCountsWithGroupByKey:+wordCountsWithGroupByKey”);“Iterables.size(intIterable)?这有多有效?如果迭代器像一百万个值呢?@Micro技术上讲,迭代器可能是无限的-在这种情况下,循环将永远持续。请注意
迭代器.size(…)
(在下面的其他注释和java文档中提到)的副作用:”返回迭代器中剩余的元素数。迭代器将处于耗尽状态:其hasNext()方法将返回false。“这意味着您以后不能再使用迭代器了。
list.newArrayList(一些迭代器);
可能会有帮助。为什么使用
AtomicInteger
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
long count = StreamSupport.stream(newIterable.spliterator(), *true*).count();
public static int getIteratorSize(Iterator iterator){
        AtomicInteger count = new AtomicInteger(0);
        iterator.forEachRemaining(element -> {
            count.incrementAndGet();
        });
        return count.get();
    }