2014-11-23 29 views
4

我有一個對象列表,我想創建另一個列表,其中只包含方法acceptable()返回「true」的對象。我的問題是我想只根據需要完成這個選擇。換句話說,我希望只有在調用iterator()方法時才能計算並填充新列表。 Java中是否有任何庫?以「懶惰」的方式篩選元素列表

我使用JDK7

+1

這是無關緊要的,但番石榴(在許多其他偉大的功能之間)提供了。查看Iterables和FluentIterable:http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/FluentIterable.html – 2014-11-23 09:10:54

回答

4

谷歌番石榴有很多的輔助方法,該類型的功能。你想要的是已經實現。

Iterators.filter如果您想要從集合中篩選迭代器。

Iterables.filter如果您需要Iterable的實例,例如在「for-each」類型的循環中使用它。

如果您還需要使用過濾器對其他收集方法進行預處理,還有Collections2.filter。

1

您可以使用Java 8流:

List<YourClass> list = ...; 

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

現在,只有當您運行的流的終端操作,它會消耗源列表,找到哪些元素通過過濾器。

+0

看起來不錯...但我還沒有在Java8中。我們仍然使用JDK7 – 2014-11-23 08:12:45

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<>接口。

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與測試,一切