Implementando um Iterator

2 respostas
Guilherme_Silveira

Estou implementando um Iterator que nao ira ter suporte ao metodo remove(), mas nao sei se o contrato do metodo seria entao jogar uma excecao de real time ou simplesmente retornar sem fazer nada.
A especificacao da API nao diz nada, soh menciona que o metodo eh opcional.

Alguem conhece alguma implementacao sem esse metodo e o que eles optaram em fazer?

Guilherme

2 Respostas

Paulo_Silveira

Quando é opcional, voce pode soltar um NotSupportedEcxeption
Mas faça o remove, e faça o alerta do ConurrentAccessException

Pra isso, da uma olhada no AbstractList, lá tem uma implementação de Iterator.

Paulo_Silveira
private class Itr implements Iterator {
	/**
	 * Index of element to be returned by subsequent call to next.
	 */
	int cursor = 0;

	/**
	 * Index of element returned by most recent call to next or
	 * previous.  Reset to -1 if this element is deleted by a call
	 * to remove.
	 */
	int lastRet = -1;

	/**
	 * The modCount value that the iterator believes that the backing
	 * List should have.  If this expectation is violated, the iterator
	 * has detected concurrent modification.
	 */
	int expectedModCount = modCount;

	public boolean hasNext() {
	    return cursor != size();
	}

	public Object next() {
	    try {
		Object next = get(cursor);
		checkForComodification();
		lastRet = cursor++;
		return next;
	    } catch(IndexOutOfBoundsException e) {
		checkForComodification();
		throw new NoSuchElementException();
	    }
	}

	public void remove() {
	    if (lastRet == -1)
		throw new IllegalStateException();
            checkForComodification();

	    try {
		AbstractList.this.remove(lastRet);
		if (lastRet < cursor)
		    cursor--;
		lastRet = -1;
		expectedModCount = modCount;
	    } catch(IndexOutOfBoundsException e) {
		throw new ConcurrentModificationException();
	    }
	}

	final void checkForComodification() {
	    if (modCount != expectedModCount)
		throw new ConcurrentModificationException();
	}
    }

Já que é uma classe interna, queria falar que a variável modCount é da classe externa, e possui o número de MODIFICÃÇÔES da coleção, e você pode entender melhor o porque disso:


The number of times this list has been structurally modified. Structural modifications are those that change the size of the list, or otherwise perturb it in such a fashion that iterations in progress may yield incorrect results.
This field is used by the iterator and list iterator implementation returned by the iterator and listIterator methods. If the value of this field changes unexpectedly, the iterator (or list iterator) will throw a ConcurrentModificationException in response to the next, remove, previous, set or add operations. This provides fail-fast behavior, rather than non-deterministic behavior in the face of concurrent modification during iteration.

Use of this field by subclasses is optional. If a subclass wishes to provide fail-fast iterators (and list iterators), then it merely has to increment this field in its add(int, Object) and remove(int) methods (and any other methods that it overrides that result in structural modifications to the list). A single call to add(int, Object) or remove(int) must add no more than one to this field, or the iterators (and list iterators) will throw bogus ConcurrentModificationExceptions. If an implementation does not wish to provide fail-fast iterators, this field may be ignored.

[/quote]

Criado 2 de setembro de 2002
Ultima resposta 2 de set. de 2002
Respostas 2
Participantes 2