Program Tip

Java에서 Iterable 크기 가져 오기

programtip 2020. 10. 18. 19:03
반응형

Java에서 Iterable 크기 가져 오기


IterableJava 의 요소 수를 알아야합니다 . 나는 이것을 할 수 있다는 것을 안다.

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

Iterable의 개체가 더 이상 필요하지 않기 때문에 이와 같은 작업을 수행 할 수도 있습니다.

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

소규모 벤치 마크에서는이 문제에 대한 성능 차이, 의견 또는 기타 아이디어가 많지 않았습니까?


요약 : Iterables.size(Iterable)위대한 구아바 라이브러리 의 유틸리티 방법 사용하십시오 .

두 코드 스 니펫 중 첫 번째 코드 스 니펫을 사용해야합니다. 두 번째 코드는에서 모든 요소를 ​​제거 values하므로 나중에 비어 있습니다. 크기와 같은 간단한 쿼리의 데이터 구조를 변경하는 것은 예상치 못한 일입니다.

성능을 위해 이것은 데이터 구조에 따라 다릅니다. 예를 들어 실제로 ArrayList이면 처음부터 요소를 제거하는 것이 (두 번째 방법이 수행하는 작업) 매우 느립니다 (크기 계산은 O (n) 대신 O (n * n)이됩니다).

일반적으로 일뿐 만 아니라 values실제로 a 일 가능성 있는 경우 이를 확인하고 다음과 같은 경우에 호출하십시오 .CollectionIterablesize()

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

에 대한 호출 size()의 뜻은 일반적으로 훨씬 빠르게 요소의 수를 계산보다,이 트릭은 정확히 무엇인가 Iterables.size(Iterable)구아바 당신을 위해 않습니다.


Java 8로 작업하는 경우 다음을 사용할 수 있습니다.

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

반복 가능한 소스의 크기가 결정된 경우에만 작동합니다. 컬렉션을위한 대부분의 Spliterator는 그럴 것이지만, HashSet또는 예 ResultSet를 들면 문제가있을 수 있습니다 .

여기 에서 javadoc을 확인할 수 있습니다 .

Java 8이 옵션이 아니 거나 iterable의 출처를 모르는 경우 guava와 동일한 접근 방식을 사용할 수 있습니다.

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

이것은 아마도 조금 늦었지만 누군가를 도울 수 있습니다. Iterable내 코드베이스에서 비슷한 문제가 발생 했으며 솔루션은 for each명시 적으로 호출하지 않고 사용하는 것이 었습니다 values.iterator();.

int size = 0;
for(T value : values) {
   size++;
}

엄밀히 말하면 Iterable에는 크기가 없습니다. 데이터 구조를 순환이라고 생각하십시오.

그리고 Iterable 인스턴스, 크기 없음을 고려하십시오.

    new Iterable(){

        @Override public Iterator iterator() {
            return new Iterator(){

                @Override
                public boolean hasNext() {
                    return isExternalSystemAvailble();
                }

                @Override
                public Object next() {
                    return fetchDataFromExternalSystem();
                }};
        }};

iterable을 목록으로 캐스트 한 다음 .size ()를 사용할 수 있습니다.

Lists.newArrayList(iterable).size();

명확성을 위해 위의 방법에는 다음 가져 오기가 필요합니다.

import com.google.common.collect.Lists;

나는 갈 것이다 it.next()간단한 이유 next()하면서 구현이 보장되는 remove()선택적인 작업입니다.

E next()

Returns the next element in the iteration.

void remove()

Removes from the underlying collection the last element returned by the iterator (optional operation).


As for me, these are just different methods. The first one leaves the object you're iterating on unchanged, while the seconds leaves it empty. The question is what do you want to do. The complexity of removing is based on implementation of your iterable object. If you're using Collections - just obtain the size like was proposed by Kazekage Gaara - its usually the best approach performance wise.


java 8 and above

StreamSupport.stream(data.spliterator(), false).count();

Why don't you simply use the size() method on your Collection to get the number of elements?

Iterator is just meant to iterate,nothing else.


Instead of using loops and counting each element or using and third party library we can simply typecast the iterable in ArrayList and get its size.

((ArrayList) iterable).size();

참고URL : https://stackoverflow.com/questions/11598977/get-size-of-an-iterable-in-java

반응형