我有一个对象列表,我想创建另一个列表,它只包含方法acceptable()
返回“true”的对象。我的问题是我想只根据需要进行选择。换句话说,我希望只有在调用iterator()
方法时才能计算和填充新列表。 Java中是否有任何库?
我正在使用JDK7
答案 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测试和所有内容