webentwicklung-frage-antwort-db.com.de

while-else-Schleife

Natürlich ist dies eine unmögliche Aussage in Java (bisher), aber im Idealfall möchte ich sie implementieren, da sie im Mittelpunkt vieler Iterationen steht. Zum Beispiel heißt es das erste Mal, dass ich es mehr als 650.000 Male mache, wenn es die ArrayList. Erstellt. Leider ist die Realität, dass mein Code nicht die set in der else-Schleife hat. Somit wird es sowohl die add- als auch die set-Befehle durchlaufen und Zeit verschwenden.

Danach habe ich es auch in einer anderen Schleife, wo es nur den Satz ausführt, da die Daten bereits erstellt wurden und dies in vielen anderen Fällen mit mehreren verschachtelt ist, so dass es ein langwieriger Prozess ist.

ArrayList<Integer>  dataColLinker = new Java.util.ArrayList<Integer>();
...
...
public void setLinkerAt( int value, int rowIndex) {
    ...
    while(rowIndex >= dataColLinker.size()) {
        dataColLinker.add(value);
    } else {
        dataColLinker.set(rowIndex, value);
    }

Irgendwelche Ideen oder Theorien? Ich bin mir bezüglich der Geschwindigkeiten in Java nicht sicher, wenn es um if-Anweisungen und ArrayList-Befehle usw. geht

8
xchiltonx

Fehlt mir etwas?

Tut dieser hypothetische Code nicht

while(rowIndex >= dataColLinker.size()) {
    dataColLinker.add(value);
} else {
    dataColLinker.set(rowIndex, value);
}

bedeuten dasselbe wie dieses?

while(rowIndex >= dataColLinker.size()) {
    dataColLinker.add(value);
}
dataColLinker.set(rowIndex, value);

oder dieses?

if (rowIndex >= dataColLinker.size()) {
    do {
        dataColLinker.add(value);
    } while(rowIndex >= dataColLinker.size());
} else {
    dataColLinker.set(rowIndex, value);
}

(Letzteres macht mehr Sinn ... denke ich). Auf jeden Fall ist es offensichtlich, dass Sie die Schleife so umschreiben können, dass der "else test" nicht innerhalb der Schleife wiederholt wird ... wie ich es gerade getan habe.


FWIW, dies ist höchstwahrscheinlich eine vorzeitige Optimierung. Das heißt, Sie verschwenden wahrscheinlich Ihre Zeit, um Code zu optimieren, der nicht optimiert werden muss:

  • Nach allem, was Sie wissen, hat der Optimierer des JIT-Compilers den Code möglicherweise bereits verschoben, sodass der "else" -Teil nicht mehr in der Schleife ist.

  • Selbst wenn dies nicht der Fall ist, besteht die Chance, dass das, was Sie optimieren möchten, kein erheblicher Engpass ist, selbst wenn es 600.000-mal ausgeführt wird.

Mein Rat ist, dieses Problem vorerst zu vergessen. Holen Sie sich das Programm zum Laufen. Wenn es funktioniert, entscheiden Sie, ob es schnell genug läuft. Wenn dies nicht der Fall ist, erstellen Sie ein Profil und verwenden Sie die Profiler-Ausgabe, um zu entscheiden, wo sich die Optimierung lohnt.

18
Stephen C

Ich verstehe nicht warum es eine Verkapselung gibt ...

Benutzen

//Use the appropriate start and end...
for(int rowIndex = 0, e = 65536; i < e; ++i){        
    if(rowIndex >= dataColLinker.size()) {
         dataColLinker.add(value);
     } else {
        dataColLinker.set(rowIndex, value);
     }    
}
3
Jay

Umbrechen Sie die Anweisung "set" in "set wenn nicht gesetzt" und legen Sie sie nackt über die while-Schleife.

Sie sind richtig, die Sprache liefert nicht genau das, wonach Sie in genau dieser Syntax suchen, aber das liegt daran, dass es Programmierparadigmen gibt, wie die, die ich gerade vorgeschlagen habe. Sie brauchen also nicht die von Ihnen vorgeschlagene Syntax.

1
djechlin
boolean entered = false, last;
while ( (entered |= last = ( condition )) && last ) {
        // Do while
} if ( !entered ) {
        // Else
}

Gern geschehen. 

Beispiel: 

boolean entered = false, last;
while ( (entered |= last = (atomic.get() > 3 && !status.destroyed()) && so on) && last ) {
        // Do while
} if ( !entered ) {
        // Else
}
0
momomo

Angenommen, Sie kommen aus Python und akzeptieren dies als dasselbe:

def setLinkerAt(value, rowIndex):
    isEnough = lambda i: return i < dataColLinker.count()
    while (not isEnough(rowIndex)):
        dataColLinker.append(value)
    else:
        dataColLinker[rowIndex] = value 

Am ähnlichsten konnte ich mir vorstellen:

public void setLinkerAt( int value, int rowIndex) {
    isEnough = (i) -> { return i < dataColLine.size; }
    if(isEnough()){
        dataColLinker.set(rowIndex, value);
    }
    else while(!isEnough(rowInex)) {
        dataColLinker.add(value);
    }

Beachten Sie die Notwendigkeit der Logik und der umgekehrten Logik. Ich bin nicht sicher, ob dies eine großartige Lösung ist (Duplizierung der Logik), aber die armbandlose Variable else ist die nächstliegende Syntax, die ich mir vorstellen kann, während sie die gleiche Aktion beibehält, wenn die Logik nicht mehr als erforderlich ausgeführt wird.

0
Jefferey Cave

Diese while-Anweisung darf den else-Code nur ausführen, wenn die Bedingung falsch ist, dh sie wird immer ausgeführt. Es gibt jedoch einen Haken: Wenn Sie das break-Schlüsselwort in der while-Schleife verwenden, sollte die else-Anweisung nicht ausgeführt werden.

Der Code, der die Bedingung erfüllt, ist nur:

boolean entered = false;
while (condition) {
   entered = true; // Set it to true stright away
   // While loop code


   // If you want to break out of this loop
   if (condition) {
      entered = false;
      break;
   }
} if (!entered) {
   // else code
}
0
Kamil B

Java hat diese Kontrollstruktur nicht.
Es sollte jedoch beachtet werden, dass andere Sprachen dies tun.
Python hat beispielsweise das while-else -Konstrukt. 

In Java können Sie dieses Verhalten nachahmen, wie Sie bereits gezeigt haben: 

if (rowIndex >= dataColLinker.size()) {
    do {
        dataColLinker.add(value);
    } while(rowIndex >= dataColLinker.size());
} else {
    dataColLinker.set(rowIndex, value);
}
0
Trevor Hickey