2016-07-04 23 views
0

Ich habe eine abstrakte Klasse und eine ArrayList<Usuario> mit Objekten seiner drei Unterklassen. Ich möchte nun die ArrayList durchlaufen und einen Wert zurückgeben, der vom Ergebnis der Verwendung von instanceof für dieses Objekt abhängt.Java benutze instanceof mit iterator

Ich erhalte einen Fehler: java.util.NoSuchElementException.

Ich nehme an, es liegt daran, dass der Iterator ein Objekt von Iterator ist und nicht von irgendeiner der Unterklassen von Usuario. Habe ich recht? Gibt es dafür eine Lösung?

public int comprobarDni(String dniAComprobar, ArrayList<Usuario> listaUsuarios) { 
    Iterator<Usuario> itUsuarios = listaUsuarios.iterator(); 
    while (itUsuarios.hasNext()) { 
     if (dniAComprobar.equals(itUsuarios.next().getDni())) { 
      if (itUsuarios.next() instanceof UsuarioBiblioteca) { 
       return 1; 
      } else if (itUsuarios.next() instanceof Bibliotecario) { 
       return 2; 
      } else if (itUsuarios.next() instanceof BibliotecaExterna) { 
       return 3; 
      } 
     } 
    } 
    return 0; 
} 

Antwort

2

Du Aufruf itUsuarios.next mehrere Male während der Iteration.

Daher könnten Sie am Ende aufrufen, während die List wurde bereits vollständig iteriert, die java.util.NoSuchElementException werfen wird.

Betrachten wir ein Usuario Wert einmal zuweisen und unter Bezugnahme auf diese statt:

while (itUsuarios.hasNext()) { 
    // reference this instead of itUsuarios.nex() for next references 
    Usuario usuario = itUsuarios.next(); 

Oder ...

Go mit schnellen Auszählung für sauberere suchen Code:

for (Usuario usuario: listaUsuarios) { 
    ... 
+0

Gute Antwort, außer der verbesserten 'for' Schleife ist nicht„schnell“. Es macht dasselbe, d. H. Verwendet einen Iterator. Es ist einfacher und sauberer Code, aber es ist kein schneller Code. Da es einfacher ist, ist es vielleicht schneller zu schreiben, aber das liest sich nicht so. – Andreas

+0

@Andreas, wenn Speicher dient, "schnelle Enumeration" ist hier nur ein Synonym für "Enhanced for Loop". Kein Anspruch auf irgendeine Leistungsverbesserung. Tatsächlich verwendet dieses Idiom tatsächlich einen Iterator hinter den Kulissen ... TL; DR schneller zu schreiben, gleiche Leistung. – Mena

4

Iterator.next() gibt das nächste Element zurück und rückt den Cursor vor. Das ist nicht das, was Sie dies so versuchen Sie stattdessen wollen:

Usuario usuario = itUsuarios.next(); 
... 

if (usuario instanceof UsuarioBiblioteca) { 
    return 1; 
} else if (usuario instanceof Bibliotecario) { 
    return 2; 
} else if (usuario instanceof BibliotecaExterna) { 
    return 3; 
} 

mit Ihrem Code betrachtet den folgenden Fall: listaUsuarios enthält nur zwei Elemente vom Typ BibliotecaExterna. Ihr erster Anruf an next() wird das erste Element zurückgeben, aber da der Typ nicht übereinstimmt, geben Sie den zweiten Aufruf an next() aus, der das zweite Element zurückgibt. Erneut stimmt der Typ nicht überein, so dass Sie einen dritten Anruf an next()() aber geben, es gibt kein drittes Element und daher erhalten Sie die NoSuchElementException.

0

Es gibt ein großes Missverständnis in Ihrem Code:

Wenn Ihr aktuelles Element eine Instanz von BibliotecaExterna ist es next() im ersten if-Anweisung aufrufe wird und überprüfen Sie sie gegen UsuarioBiblioteca. Aber dann hat sich das Element schon verändert.

Stattdessen speichern Sie es am Anfang:

Usuario element = itUsuarios.next(); 
if(element instance of ...) 
...