Dies ist mein Java-Code:
%Vor%Ich habe zwei Fragen:
objects.size()
nur einmal vor der Angabe der Schleife berechnet oder wird jede Schleife berechnet? 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?
Antworten:
objects.size()
wird in jeder Schleife genannt (ob berechnet von der ArrayList-Implementierung abhängt, die Sie nicht interessieren sollten) Echte Antwort:
Sie sollten sich nicht kümmern müssen, und hier ist, wie Sie nicht müssen:
foreach
-Syntax, was bedeutet, dass Sie keinen Index usw. verwenden müssen - es ist für Sie erledigt: %Vor%
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
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.
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.
- Wird objects.size () nur einmal berechnet, bevor die Schleife angegeben wird, oder wird jede Schleife berechnet?
Jedes Mal.
- Wenn objects.size () für jede Schleife berechnet wird, wenn ein anderer Thread sie gleichzeitig ohne Multithread-Schutz ändert, kann der Code abstürzen.
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.
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.
Tags und Links java optimization loops