Wird die Schleifenbedingung für "for" Sätze in Java berechnet?

7

Dies ist mein Java-Code:

%Vor%

Ich habe zwei Fragen:

  1. Wird objects.size() nur einmal vor der Angabe der Schleife berechnet oder wird jede Schleife berechnet?
  2. Wenn objects.size() für jede Schleife berechnet wird, wird der Code möglicherweise abgestürzt, wenn ein anderer Thread ihn gleichzeitig ohne Multithread-Schutz ändert.

Habe ich Recht?

    
flypen 08.12.2011, 05:42
quelle

6 Antworten

10

Antworten:

  1. objects.size() wird in jeder Schleife genannt (ob berechnet von der ArrayList-Implementierung abhängt, die Sie nicht interessieren sollten)
  2. Ja, ein anderer Thread kann die Liste ändern und dies hat Auswirkungen auf Ihre Schleife

Echte Antwort:

Sie sollten sich nicht kümmern müssen, und hier ist, wie Sie nicht müssen:

  1. Verwenden Sie eine CopyOnWriteArrayList , bei der es sich um einen Thread handelt -sicher. Wenn Sie mit einem Iterator (wie die Foreach-Syntax intern verwendet) über iterieren, durchlaufen Sie die Liste wie zu Beginn der Iteration
  2. Verwenden Sie die foreach -Syntax, was bedeutet, dass Sie keinen Index usw. verwenden müssen - es ist für Sie erledigt:

%Vor%     
Bohemian 08.12.2011, 05:47
quelle
7

Ja, es wird jedes Mal berechnet. Wenn Sie einen anderen Thread haben, der die Größe Ihrer Objektliste ändert, ändert sich die Schleifenbedingung ständig.

    
Todd 08.12.2011 05:44
quelle
2

ja, wenn Sie objects.size() innerhalb der Schleifenbedingung verwenden, berechnet es jedes Mal. besser ist es, es in einer Variablen zu belassen, bevor es in die Schleife geht; wie int

%Vor%

Wenn Sie einen anderen Thread haben, können Sie ihn ändern, aber mit der obigen Option wird Ihr Programm nicht beeinträchtigt oder zum Absturz gebracht.

    
Hemant Metalia 08.12.2011 05:44
quelle
1

Ja, es wird jedes Mal berechnet

Wenn Sie nach einer Schleifenanweisung suchen, wird in der ersten Anweisung der Initialwert des Zählers gesetzt dann wird es auf den maximalen Wert prüfen, dann wird es für den Schleifenkörper ausgeführt, dann wird es den Wert des Zählers erhöhen und dann erneut auf den maximalen Wert prüfen. Jedes Mal, um den Maximalwert zu überprüfen, wird die Größenmethode aufgerufen.

    
Ashish 08.12.2011 05:49
quelle
1
  
  1. Wird objects.size () nur einmal berechnet, bevor die Schleife angegeben wird, oder wird jede Schleife berechnet?
  2.   

Jedes Mal.

  
  1. Wenn objects.size () für jede Schleife berechnet wird, wenn ein anderer Thread sie gleichzeitig ohne Multithread-Schutz ändert, kann der Code abstürzen.
  2.   

Ja. Oder zumindest erhalten Sie eine ConcurrentModificationException , und haben keinen vernünftigen Weg, damit umzugehen.

Bitte beachten Sie, dass dies auch dann passieren kann, wenn Sie objects.size() zwischengespeichert haben, außer dass die .get() stattdessen fehlschlägt, weil Sie versuchen, einen Index zu erhalten, der nicht mehr existiert. objects.size() ändert sich, weil etwas aus dem Container entfernt oder hinzugefügt wird.

Ändern Sie Sammlungen nicht, während Sie über sie hinweg iterieren.

    
Karl Knechtel 08.12.2011 05:51
quelle
1

Notional kann die objects.size () in jeder Schleife ausgewertet werden. Da die Methode jedoch kurz ist, kann sie inline und zwischengespeichert werden, da sie keine flüchtige Variable ist. ein anderer Thread könnte es ändern, aber es gibt keine Garantie, dass Sie die Änderung sehen würden, wenn dies der Fall wäre.

Ein kurzer Weg, um die Größe zu speichern, ist die Verwendung des folgenden.

%Vor%

Wenn Sie jedoch Bedenken haben, dass ein anderer Thread die Größe ändern könnte, schützt dieser Ansatz Sie nur, wenn ein Objekt hinzugefügt wird. Wenn ein Objekt entfernt wird, können Sie immer noch eine Ausnahme erhalten, wenn Sie versuchen, auf den Wert zuzugreifen, der jetzt über das Ende der Liste hinausgeht.

Die Verwendung einer CopyOnWriteArrayList vermeidet diese Probleme (sofern Sie einen Iterator verwenden), macht jedoch das Schreiben teurer.

    
Peter Lawrey 08.12.2011 08:05
quelle

Tags und Links