What is the best way to get the count/length/size of an iterator?

后端 未结 9 996
青春惊慌失措
青春惊慌失措 2020-12-03 00:01

Is there a \"computationally\" quick way to get the count of an iterator?

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

相关标签:
9条回答
  • 2020-12-03 00:40

    Using Guava library, another option is to convert the Iterable to a 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.

    0 讨论(0)
  • 2020-12-03 00:43

    Using Guava library:

    int size = Iterators.size(iterator);
    

    Internally it just iterates over all elements so its just for convenience.

    0 讨论(0)
  • 2020-12-03 00:53

    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");
            }
        }; 
    
    0 讨论(0)
  • 2020-12-03 00:53

    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 讨论(0)
  • 2020-12-03 00:54

    You will always have to iterate. Yet you can use Java 8, 9 to do the counting without looping explicitely:

    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:

    long count = StreamSupport.stream(newIterable.spliterator(), *true*).count();
    
    0 讨论(0)
  • 2020-12-03 00:55

    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 ...)

    0 讨论(0)
提交回复
热议问题