2015-07-13 2 views
0

Как вы код Iterator для Set? Учитывая, что итератор не имеет доступа к основному механизму хранения данных и может использовать только методы Set, можно ли это сделать?Реализация итератора для набора, отслеживание текущего элемента

Каждая реализация, которую мне удалось найти, создает Iterator как анонимный класс; Тем не менее, я пытаюсь выяснить, есть ли умный способ перебора более Set, а только доступ к методам, предоставленным Set.

До сих пор лучшее, что я смог придумать выглядит следующим образом:

import java.util.*; 

public class SetIterator<E> implements Iterator 
{ 
    protected E[] arrayData; 
    protected Set<E> set; 
    protected int index; 
    protected boolean canRemove; 

    public SetIterator(Set<E> set) 
    { 
     this.set = set; 
     this.arrayData = (E[]) set.toArray(); 
     this.index = -1; 
     this.canRemove = false; 
    } 

    public E next() 
    { 
     if(this.hasNext()) 
     { 
      this.canRemove = true; 
      return this.arrayData[++this.index]; 
     } 
     else 
     { 
      throw new NoSuchElementException("There is no next element"); 
     } 
    } 

    public boolean hasNext() 
    { 
     return this.index + 1 < this.arrayData.length; 
    } 

    public void remove() 
    { 
     if(this.canRemove) 
     { 
      this.set.remove(this.arrayData[index--]); 
      this.arrayData = (E[]) this.set.toArray(); 
      this.canRemove = false; 
     } 
     else 
     { 
      throw new IllegalStateException("Cannot remove element before calling next"); 
     } 
    } 
} 

Но что чувствует себя довольно запутано .... есть лучший способ?

+1

Возможно, я что-то пропустил, но разве ваш итератор не является обертой вокруг Итерабельного? Зачем вам это нужно, а не просто использовать Set напрямую? –

+0

Я смущен. Вам интересно, зачем мне нужен итератор? Что вы подразумеваете под прямым набором? – MirroredFate

+0

'Set' реализует' Collection', который (в свою очередь) реализует 'Iterable' с обязательным [' iterator'] (http://docs.oracle.com/javase/7/docs/api/java/lang/Iterable. html # iterator()). –

ответ

0

Я думаю, ваш заголовок не оставляет много места для ответов, но, если я использую следующий как ваш актуальный вопрос:

Как построить итератор для набора?

(и понимать строить как в получить экземпляр)

Я думаю, как PM 77-1 указал в комментариях: Вызовите iterator() method на нем, что он имеет с at least Java 1.5.

Имейте в виду, что это зависит от фактической реализации Set, поэтому элементы всегда будут повторяться в том же порядке.

+0

Ах, я думаю, что это источник замешательства. Спасибо, что объяснил это мне. Я не хочу получать экземпляр, я хочу написать его. – MirroredFate

+0

Я прочитал ваш комментарий выше на другом языке (но я не хватало репутации, чтобы ответить на комментарии выше), почему вы используете «java в качестве шаблона» и не говорите, на каком языке вы говорите? Но так или иначе: я полагаю, вы не можете коснуться множества или его внутренней структуры? Тогда я думаю, что ваше решение в порядке. (И я думаю, что никто не сможет обеспечить лучшую, если вы будете говорить о Java;)) – karfau

+0

Язык - это PHP, у которого не будет анонимных классов до [7.0] (https: //wiki.php. сеть/гк/anonymous_classes). Это должно быть [PSR] (http://www.php-fig.org/) совместимым. Я также создаю 'Set', но из-за вышеперечисленных ограничений это мне очень не помогает. – MirroredFate

0

Если мы посмотрим в AbstractCollection, мы увидим, что toArray на самом деле вызывает итератор() (абстрактный метод) для создания массива, который вы будете использовать, поэтому ваш метод все еще зависит от конкретного итератора, поэтому вы по существу украшаете итератор ,

public Object[] toArray() { 
    // Estimate size of array; be prepared to see more or fewer elements 
    Object[] r = new Object[size()]; 
    Iterator<E> it = iterator(); 
    for (int i = 0; i < r.length; i++) { 
     if (! it.hasNext()) // fewer elements than expected 
      return Arrays.copyOf(r, i); 
     r[i] = it.next(); 
    } 
    return it.hasNext() ? finishToArray(r, it) : r; 
} 

До сих пор не уверен, что вы пытаетесь достичь, основная структура данных множества будет иметь различные (и конкретные) способы efficently перебирать данные, любое общее решение будет sacrafice производительность, используя итератор интерфейс должен быть достаточно общего.

Смежные вопросы