在 Java 中获取可迭代对象的大小

2022-08-31 10:17:44

我需要弄清楚Java中元素的数量。我知道我可以做到这一点:Iterable

Iterable values = ...
it = values.iterator();
while (it.hasNext()) {
  it.next();
  sum++;
}

我也可以做这样的事情,因为我不再需要迭代器中的对象:

it = values.iterator();
while (it.hasNext()) {
  it.remove();
  sum++;
}

小规模的基准测试没有显示出太大的性能差异,对这个问题有什么评论或其他想法吗?


答案 1

TL;DR:使用伟大的番石榴库的实用方法迭代(迭代)。

在两个代码片段中,您应该使用第一个,因为第二个代码片段将从 中删除所有元素,因此之后它是空的。更改简单查询的数据结构(如其大小)是非常意外的。values

为了提高性能,这取决于您的数据结构。例如,如果它实际上是一个,从头开始删除元素(你的第二种方法正在做什么)是非常慢的(计算大小变成O(n*n)而不是O(n)应该)。ArrayList

一般来说,如果有机会实际上是 a 而不仅仅是 a,请检查此值并在万一的情况下调用:valuesCollectionIterablesize()

if (values instanceof Collection<?>) {
  return ((Collection<?>)values).size();
}
// use Iterator here...

调用通常比计算元素数量快得多,而这个技巧正是番石榴Iterables.size(Iterable)为你做的。size()


答案 2

如果您使用的是java 8,则可以使用:

Iterable values = ...
long size = values.spliterator().getExactSizeIfKnown();

仅当可迭代源具有确定的大小时,它才有效。大多数用于集合的拆分器都会,但是如果它来自 或 例如,您可能会遇到问题。HashSetResultSet

你可以在这里查看javadoc。

如果Java 8不是一个选项,或者你不知道可迭代来自哪里,你可以使用与番石榴相同的方法:

  if (iterable instanceof Collection) {
        return ((Collection<?>) iterable).size();
    } else {
        int count = 0;
        Iterator iterator = iterable.iterator();
        while(iterator.hasNext()) {
            iterator.next();
            count++;
        }
        return count;
    }

推荐