以“懒惰”方式过滤掉元素列表

时间:2014-11-23 08:03:50

标签: java

我有一个对象列表,我想创建另一个列表,它只包含方法acceptable()返回“true”的对象。我的问题是我想只根据需要进行选择。换句话说,我希望只有在调用iterator()方法时才能计算和填充新列表。 Java中是否有任何库?

我正在使用JDK7

4 个答案:

答案 0 :(得分:4)

Google Guava为此类功能提供了许多辅助方法。你想要的已经实现了。

Iterators.filter如果你想从一个集合中装载一个迭代器。

Iterables.filter如果你需要一个Iterable实例,例如在" for-each"中使用它。循环类型。

如果您还需要使用过滤器预处理其他集合方法,还有Collections2.filter。

答案 1 :(得分:1)

您可以使用Java 8 Streams:

List<YourClass> list = ...;

Stream<YourClass> filteredList = list.filter(YourClass::acceptable());

现在,只有当您在Stream上运行终端操作时,它才会使用源列表并查找哪些元素通过了过滤器。

答案 2 :(得分:1)

我不知道是否有库来实现这一目标,但你可以制作一些类似于这样的列表包装器:

public class ResolveList<T extends MyClass> implements Iterable<T> {
//T extends MyClass for access to MyClass.acceptable()
    private final List<T> rawList;
    private List<T> processedList;
    public List<T> getList() {
        if(processedList == null) {
            processList();
        }
        return processedList; //check if null
    }

    public ResolveList(List<T> list) {
        this.rawList = list;
    }

    private void processList() {
        processedList = new ArrayList<T>(); //or whatever kind of list you prefer.
        for(T t : rawList) {
            if(t.acceptable()) {
                processedList.add(t);
            }
        }
    }

    @Override
    public Iterator<T> iterator() {
        return this.getList().iterator();
    }
}

您可以使用内置迭代器或获取列表本身。 或者,您可以删除getList()功能并自行实施List<>界面。

答案 3 :(得分:1)

不知道是否有这样的库,但这是一项简单的任务。这是一个LazyIterator:

public class LazyIterator<E extends Acceptable> implements Iterator<E> {
    private final Iterator<E> iterator;
    private boolean hasNext;
    private E next;

    public LazyIterator(Iterator<E> iterator) {
        this.iterator = iterator;
        iterate();
    }

    private void iterate() {
        hasNext = false;
        while (iterator.hasNext()) {
            next = iterator.next();
            if (next.accept()) {
                hasNext = true;
                break;
            }
        }
    }

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

    @Override public E next() {
        if (!hasNext) throw new NoSuchElementException();
        E out = next;
        iterate();
        return out;
    }

    @Override public void remove() { throw new RuntimeException("N/A"); }
}

这就是包装器LazyIterable

public class LazyIterable<E extends Acceptable> implements Iterable<E> {

    private final Iterable<E> wrapped;

    public LazyIterable(Iterable<E> wrapped) {
        this.wrapped = wrapped;
    }

    @Override
    public Iterator<E> iterator() {
        return new LazyIterator<E>(wrapped.iterator());
    }
}

Here is the full gist测试和所有内容