将ListIterator限制为前N个元素(已优化)

fin*_*nnw 7 java collections iterator guava

什么是一个简单快速的方法来获得一个从一开始就返回最多N个元素的迭代器List

我能想出的最简单的版本是:

#1:

import com.google.common.collect.Iterators;

// ...

public static <E> Iterator<E> lengthLimitedIterator(Iterable<E> source, int maxLen) {
    return Iterators.partition(source.iterator(), maxLen).next().iterator();
}
Run Code Online (Sandbox Code Playgroud)

#2:

public static <E> Iterator<E> lengthLimitedIterator(List<E> source, int maxLen) {
    return source.subList(0, Math.min(source.size(), maxLen)).iterator();
}
Run Code Online (Sandbox Code Playgroud)

不幸的是,两个版本都创建了一个临时性List,这会显着影响性能,因为我在紧密循环中调用了这个方法数百万次

我可以使用其他任何库函数吗?


注意:我无法避免遍历列表,因为我将它传递给一个以迭代器作为参数的方法,我无法修改该类.

Ric*_*chN 14

你已经知道它是一个列表,所以你可以调用该List.subList(int fromIndex, int toIndex)方法.根据规范,subList由原始列表支持,因此它不是真正创建一个完整的List,只是某种代理对象.


Wer*_*ann 8

似乎该功能将被添加到番石榴,目前(从r06开始)测试中:

public static <T> Iterator<T> limit(Iterator<T> iterator, int limitSize)
Run Code Online (Sandbox Code Playgroud)

  • 除了`Iterators`之外,请注意[Iterables`也具有`limit()`方法](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Iterables.html #limit(java.lang.Iterable,%20int))。因此,如果您有一个“列表”,那么执行“ Iterables.limit(aList,3)”是最简单的。 (2认同)

kdg*_*ory 5

这是一个装饰器工作得非常好的地方:装饰器保持计数,计数增加next(),并由控制使用hasNext().

示例(故意不完整):

public class LengthLimitedIterator<T>
implements Iterator<T>
{
    private Iterator<T> _wrapped;
    private int _length;
    private int _count;

    public LengthLimitedIterator(Iterator<T> wrapped, int length)
    {
        _wrapped = wrapped;
        _length = length;
    }


    public boolean hasNext()
    {
        if (_count < _length)
            return _wrapped.hasNext();
        return false;
    }

    public T next()
    {
        // FIXME - add exception if count >= length
        _count++;
        return _wrapped.next();
    }
Run Code Online (Sandbox Code Playgroud)


mer*_*ike 5

为什么不简单

list.subList(0, 42).iterator();
Run Code Online (Sandbox Code Playgroud)

我不确定你为什么要介意创建那个临时列表.它没有做任何我认为昂贵的事情.事实上,创建这个列表远比迭代它便宜,我假设你这样做.