Perché Java Iterator e ListIterator puntano tra gli elementi?

9

Il Javadoc per ListIterator dice:

A ListIterator has no current element; its cursor position always lies between the element that would be returned by a call to previous() and the element that would be returned by a call to next().

Perché la ListIterator di Java è stata implementata per puntare tra gli elementi anziché su un elemento corrente? Sembra che questo renda il codice client meno leggibile quando deve chiamare ripetutamente getNext() , getPrevious() , quindi presumo che ci debba essere una buona ragione per la scelta.

Come nota a margine, ho appena scritto una piccola libreria chiamata peekable-arraylist che estende ArrayList , Iterator e ListIterator che fornisce metodi peekAtNext() e peekAtPrevious() implementati come:

  @Override public synchronized T peekAtNext() {
     T t = next();
     previous();
     return t;
  }
    
posta glenviewjeff 03.03.2012 - 22:19
fonte

1 risposta

11

Per quanto posso dire, la ragione può essere trovata nella parte di javadoc che non hai citato (enfasi sotto la mia):

An iterator for lists that allows the programmer to traverse the list in either direction, modify the list during iteration...

Come vedi, lo scopo è quello di consentire l'uso mentre la lista è in fase di modifica. Eventuali modifiche apparentemente includono rimozione degli elementi.

Ora pensate a cosa succederebbe se rimuovessimo un elemento che sarebbe current() per iteratore - assumendo che l'iteratore abbia una nozione di elemento corrente? In questo contesto, il modo di implementarlo senza una nozione di elemento corrente mi sembra molto sensato - perché in questo modo, l'iteratore non deve preoccuparsi della rimozione degli elementi.

È importante notare che javadoc non richiede che le implementazioni dell'interfaccia siano thread-safe.

  • Per questo motivo, non ci si dovrebbe aspettare una corretta gestione delle modifiche fatte da thread diversi - per questo l'implementazione dovrebbe fornire mezzi aggiuntivi per sincronizzare l'accesso, garantire la visibilità ecc. come specificato da Java Memory Model per JSR 133 .

Di cosa è capace ListIterator, gestisce le modifiche eseguite dallo stesso thread durante l'iterazione. Non tutti gli iteratori sono così, ConcurrentModificationException javadocs specificatamente avvisano di questo :

...Note that this exception does not always indicate that an object has been concurrently modified by a different thread. If a single thread issues a sequence of method invocations that violates the contract of an object, the object may throw this exception. For example, if a thread modifies a collection directly while it is iterating over the collection with a fail-fast iterator, the iterator will throw this exception...

    
risposta data 03.03.2012 - 22:54
fonte

Leggi altre domande sui tag