2013-04-30 9 views
1

Я пытаюсь создать итератор итератора, поддерживающий любой тип Java. Цель состоит в том, чтобы перебирать объекты итераторов.Итератор Итератора

Но у меня есть несоответствие типа, и я не вижу, как инициализировать мою реализацию.

Первой идеей, которую я имел в виду, является создание моего класса Iterator<Iterator<T>>, но это не сработает, потому что следующий метод будет иметь подпись public Iterator<T> next(), которая не соответствует тому, что я хочу сделать. Вместо того, чтобы возвращать Iterator<T>, я хочу вернуть тип T.

Так я создаю другой интерфейс, который очень похож на интерфейс итератора:

public interface MyIterator<T extends Iterator<T>> { 

    public boolean hasNext(); 

    public T next(); 
} 

Мой итератор принимает тип T, который является итератор. Вот моя реализация (не удаляя):

public class IteratorOfIterator<T extends Iterator<T>> implements MyIterator<T> { 

private T[] iterators; 

private T currentIterator; 

private int currentIndex; 

public IteratorOfIterator(T[] iterators){ 
    this.iterators = iterators; 
    this.currentIndex = 0; 
    this.currentIterator = iterators[currentIndex]; 
} 

public boolean hasNext() { 
    return currentIndex < iterators.length - 1 || currentIterator.hasNext(); 
} 

public T next() { 
    if(!this.currentIterator.hasNext()){ 
     currentIndex++; 
     this.currentIterator = iterators[currentIndex]; 
    } 
    return currentIterator.next(); 
} 

Если я хочу, чтобы проверить мой итератор, но у меня есть несоответствие типов, как я могу инициализировать его? Вот пример того, что я хочу сделать:

String[] strings = {"peanut","butter","coco","foo","bar"}; 

Object[] iterators = {strings}; 

MyIterator<String> myIterator = new IteratorOfIterator<String>(iterators); // <-- in this line 

Ошибка говорит: Bound mismatch: The type String is not a valid substitute for the bounded parameter <T extends Iterator<T>> of the type IteratorOfIterator<T> IteratorOfIterator.java

Как я могу решить эту проблему? Большое спасибо за ваш совет.

PS: Я полностью понимаю проблему. Я понимаю, что, например, тип String не реализует интерфейс MyIterator, поэтому он не является хорошей заменой. Моя проблема, я не знаю, как можно

ответ

2

Это не будет работать,

public interface MyIterator<T extends Iterator<T>> 

Это означает, что T должен быть Iterator сам.

Вы не хотите T делать ограничивается конкретным типом,

public interface MyIterator<T> 

НО вы хотите, чтобы ваши итераторы быть типа Iterator<T>

public class IteratorOfIterator<T> implements Iterator<T> { 

private Iterator<T>[] iterators; 

private Iterator<T> currentIterator; 

private int currentIndex; 

public IteratorOfIterator(Iterator<T>[] iterators){ 
    this.iterators = iterators; 
    this.currentIndex = 0; 
    this.currentIterator = iterators[currentIndex]; 
} 

так что вы можете использовать Iterator вместо MyIterator еще раз.

+0

Хорошо, я собираюсь проверить это – Dimitri

0

Вы можете использовать

Iterator<String> myIterator = Arrays.asList(strings).iterator(); 

Там нет стандартного способа напрямую получить итератор из массива Java, так что вы можете либо сначала преобразовать его в List, или создайте свой собственный итератор для массива.

0

вы создаете итератор итератора и конструкторы определяют массив итераторов, поэтому код вызова должен быть как:

List list1 = new ArrayList(); 
    List list2 = new ArrayList(); 
    Iterator<String> iterator1 = list1.iterator(); 
    Iterator<String> iterator2 = list2.iterator();  
    Iterator[] iteratorList = {iterator1, iterator2};  
    MyIterator<String> myIterator = new IteratorOfIterator(iteratorList); 
0

Цель IteratorOfIterator чтобы скрыть детали реализации иметь дело с несколькими итераторами, так что клиент выполняет итерацию через элементы как один итератор. В некотором смысле IterorOfIterator выступает в качестве адаптера для других итераторов.See this page for the concept - RoundRobinIterator

В коде здесь используется очередь для поддержания последовательности итераторов. Переменная 'currentIter' устанавливается путем опроса из очереди. setNext - это конечный автомат, который проходит между итераторами и устанавливает следующее значение для итерации.

public class IteratorOfIterator<T> implements Iterator<T> { 
private final Queue<Iterator<T>> iterQueue; 
private Iterator<T> currentIter; 
private T nextValue; 

public IteratorOfIterator(List<Iterator<T>> iters) { 
    this.iterQueue = new LinkedList<Iterator<T>>(iters); 
    this.currentIter = null; 
    this.nextValue = null; 
} 

@Override 
public boolean hasNext() { 
    return this.nextValue != null || setNext(); 
} 

@Override 
public T next() { 
    if (this.nextValue != null) { 
     T next = this.nextValue; 
     this.nextValue = null; 
     setNext(); 
     return next; 
    } 
    return null; 
} 

private boolean setNext() { 
    while (true) { 
     if (currentIter == null && iterQueue.isEmpty()) { 
      return false; 
     } 
     if (currentIter == null && !iterQueue.isEmpty()) { 
      currentIter = iterQueue.poll(); 
     } 
     if (currentIter != null && currentIter.hasNext()) { 
      this.nextValue = currentIter.next(); 
      return true; 
     } 
     if (currentIter != null && !currentIter.hasNext()) { 
      if (!iterQueue.isEmpty()) { 
       currentIter = iterQueue.poll(); 
      } else { 
       currentIter = null; 
      } 
     } 
    } 
} 
Смежные вопросы