2011-03-29 7 views
9
  1. IObjectTest FilteringIterator başka Yineleyiciyi ve IObjectTest örneği ile başlatılır olan Yineleyiciyi bir uygulamasıdırBu FilteringIterator nasıl uygulanır? Yeni FilteringIterator (myIterator:

  2. bir tek Boole testi (Obje o) olan bir arayüz yöntemidir myTest). FilteringIterator'ınız olacaktır, ardından 'myIterator' üzerinden yinelemeye izin verin, ancak 'myTest' testini geçmeyen nesneleri atlayın. "HasNext" işlemi aslında repeatly sonraki eşleşen öğe ulaşmak e kadar altta yatan yineleyici taşıması yapılıyor yana

. Asıl soru, hasNext'in temeldeki yineleyiciyi hareket ettirmemesi gerektiğinden, yinelemeyi nasıl tekrar çalıştırabileceğidir.

+1

public class PredicateIterator implements Iterator { private Iterator iterator; private Predicate predicate; private Object cached; private boolean hasNextCached; private boolean hasNext; public PredicateIterator(Iterator iterator, Predicate predicate) { this.iterator = iterator; this.predicate = predicate; } @Override public boolean hasNext() { if (hasNextCached) { return hasNext; } else { return findNextMatch(); } } private boolean findNextMatch() { boolean match = false; while(!match && iterator.hasNext()) { cached = iterator.next(); match = predicate.test(cached); } hasNextCached = true; hasNext = match; return match; } @Override public Object next() { if (hasNext()) { hasNextCached = false; return cached; } else { throw new NoSuchElementException(); } } @Override public void remove() { iterator.remove(); } 

}. Leon, eğer olmasan beni düzelt! –

+0

evet, öyle. Teşekkürler! – Leon

cevap

5

Yineleyicinizi durumsal hale getirmeniz gerekir. hasNext'dan aldığınız son değeri önbelleğe alın ve varsa next yönteminden kullanın.

private boolean hasCached; 
private T cached; 

public boolean hasNext() { 
    if (hasCached) return true; 
    //iterate until you find one and set hasCached and cached 
} 

public T next() { 
    if (hasCached) { 
     hasCached = false; 
     return cached; 
    } 
    //iterate until next matches 
} 
9

Eğer bunu kendiniz yapmak isterseniz, aşağıda yazdıklarıma benzer bir kod kullanabilirsiniz. Ancak, ben kullanmak tavsiye edersiniz Guava en Iterators.filter(Iterator, Predicate)

public class FilteredIterator<T> implements Iterator<T> { 
    private Iterator<? extends T> iterator; 
    private Filter<T> filter; 
    private T nextElement; 
    private boolean hasNext; 

    /** 
    * Creates a new FilteredIterator using wrapping the iterator and returning only elements matching the filter. 
    * 
    * @param iterator 
    *   the iterator to wrap 
    * @param filter 
    *   elements must match this filter to be returned 
    */ 
    public FilteredIterator(Iterator<? extends T> iterator, Filter<T> filter) { 
     this.iterator = iterator; 
     this.filter = filter; 

     nextMatch(); 
    } 

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

    @Override 
    public T next() { 
     if (!hasNext) { 
      throw new NoSuchElementException(); 
     } 

     return nextMatch(); 
    } 

    private T nextMatch() { 
     T oldMatch = nextElement; 

     while (iterator.hasNext()) { 
      T o = iterator.next(); 

      if (filter.matches(o)) { 
       hasNext = true; 
       nextElement = o; 

       return oldMatch; 
      } 
     } 

     hasNext = false; 

     return oldMatch; 
    } 

    @Override 
    public void remove() { 
     throw new UnsupportedOperationException(); 
    } 
} 

public interface Filter<T> { 

    /** 
    * Determines whether elements should be filtered or not. 
    * 
    * @param element the element to be matched against the filter 
    * @return {@code true} if the element matches the filter, otherwise {@code false} 
    */ 
    public boolean matches(T element); 
} 
+0

teşekkürler. Bu tam olarak aradığım şey. –

+1

Merhaba Roel, herhangi bir iyi neden remove() desteklenemiyor? – Zeiga

+0

Hayır, bu nedenle kaldırmayı yineleme yinelemesine çağırmak için kod güncelledim. İyi arama! –

0

Sürümüm nasıl? next() yöntemi, önceki örneklerle karşılaştırmak için biraz kolay olabilir. ifadeler çok buna olduğu gibi sesler yapar çünkü bu "ev ödevi" etiketlediniz