Java: Mehrere Variablen für for loop init initialisieren?


89

Ich möchte zwei Schleifenvariablen unterschiedlichen Typs haben. Gibt es eine Möglichkeit, diese Arbeit zu machen?

@Override
public T get(int index) throws IndexOutOfBoundsException {
    // syntax error on first 'int'
    for (Node<T> current = first, int currentIndex; current != null; 
            current = current.next, currentIndex++) {
        if (currentIndex == index) {
            return current.datum;
        }
    }
    throw new IndexOutOfBoundsException();
}

Was ist first? Es wird nirgendwo deklariert. Ist es ein Klassenmitglied?
extraneon

7
Sie sollten eine Antwort unten akzeptieren
Mr_and_Mrs_D

Und im Gegensatz zu C verfügt Java nicht über den Komma-Operator: stackoverflow.com/questions/12601596/… , mit dem zwei Variablen unterschiedlichen Typs initialisiert (aber nicht deklariert) werden können.
Ciro Santilli 法轮功 冠状 病 六四 事件 26

@ Nick Heiner Könnten Sie bitte eine der folgenden Antworten als akzeptiert markieren?
James Monger

Antworten:


103

Die Initialisierung einerfor Anweisung folgt den Regeln für lokale Variablendeklarationen .

Dies wäre legal (wenn dumm):

for (int a = 0, b[] = { 1 }, c[][] = { { 1 }, { 2 } }; a < 10; a++) {
  // something
}

Aber versuchen, das eindeutige Nodeund zu erklärenint Typen wie gewünscht ist für lokale Variablendeklarationen jedoch nicht zulässig.

Sie können den Umfang zusätzlicher Variablen innerhalb von Methoden einschränken, indem Sie einen Block wie den folgenden verwenden:

{
  int n = 0;
  for (Object o = new Object();/* expr */;/* expr */) {
    // do something
  }
}

Dies stellt sicher, dass Sie die Variable nicht versehentlich an anderer Stelle in der Methode wiederverwenden.


9
Hat jemand eine Idee, warum die Sprachdesigner diese scheinbar unnötige Einschränkung implementiert haben?
Jeff Axelrod

@glenviewjeff - das sollte am besten als separate Frage gestellt werden.
McDowell

1
@ JeffAxelrod, vielleicht aus historischen Gründen, weil Java nach C ++ modelliert wurde ... siehe diesen Beitrag: stackoverflow.com/questions/2687392/…
Christophe Roussy

2
+1 für die Verwendung eines Blocks, ich benutze sie oft, immer noch besser als dumme Fehler zu machen
Christophe Roussy

18

Das kannst du nicht mögen. Entweder verwenden Sie mehrere Variablen desselben Typs for(Object var1 = null, var2 = null; ...)oder Sie extrahieren die andere Variable und deklarieren sie vor der for-Schleife.


9

Verschieben Sie einfach die Variablendeklarationen ( Node<T> current, int currentIndex) außerhalb der Schleife, und es sollte funktionieren. Etwas wie das

int currentIndex;
Node<T> current;
for (current = first; current != null; current = current.next, currentIndex++) {

oder vielleicht sogar

int currentIndex;
for (Node<T> current = first; current != null; current = current.next, currentIndex++) {

1
Beides wird nicht kompiliert: Sie müssen Variablen vor der Verwendung initialisieren.
unbeli

@unbeli Nun, ich habe nicht in der manuellen Code-Kompilierung trainiert :) Ich wollte nur die Idee geben.
Nikita Rybak

3
@unbeli: Nur zur Klarstellung: currentIndex muss initialisiert werden. Das erste, was Nikita damit macht, ist "currentIndex ++", was natürlich die Frage aufwirft, was inkrementieren? Strom ist in Ordnung, da die erste Verwendung darin besteht, ihn zuerst einzustellen.
Jay

Um eine Inkrementierung in eine for-Schleife besser schreiben zu können, sollte normalerweise ++ var als Notation var ++ verwendet werden, die vom Compiler benötigt wird, um den Inhalt der var zu duplizieren, bevor er inkrementiert wird, um ihn als Ergebnis des Ausdrucks zurückzugeben, obwohl dies niemand jemals möchte. Natürlich wird der Compiler das optimieren, aber es ist, als würde man Müll auf die Straße werfen und darauf warten, dass andere aufräumen.
Chucky

5

Im Initialisierungsblock deklarierte Variablen müssen vom gleichen Typ sein

Wir können die verschiedenen Datentypen in der for-Schleife nicht gemäß ihrem Design initialisieren. Ich gebe nur ein kleines Beispiel.

for(int i=0, b=0, c=0, d=0....;/*condition to be applied */;/*increment or other logic*/){
      //Your Code goes here
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.