Java: Zainicjować wiele zmiennych w init pętli for?

92

Chcę mieć dwie zmienne pętli różnych typów. Czy jest jakiś sposób, aby to zadziałało?

@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();
}
Nick Heiner
źródło
Co to jest first? Nigdzie nie jest deklarowane. Czy to jest członek klasy?
extraneon
7
Powinieneś zaakceptować jedną odpowiedź poniżej
Mr_and_Mrs_D
W przeciwieństwie do C, Java nie ma operatora przecinka: stackoverflow.com/questions/12601596/… , który pozwoliłby zainicjować (ale nie zadeklarować) dwie zmienne różnych typów.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
@Nick Heiner Czy mógłbyś oznaczyć jedną z poniższych odpowiedzi jako zaakceptowaną?
James Monger

Odpowiedzi:

105

Inicjalizacjifor oświadczenie następujące zasady deklaracji zmiennych lokalnych .

Byłoby to legalne (jeśli głupie):

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

Ale próba zadeklarowania różnych typów Nodei inttypów, jak chcesz, nie jest dozwolona dla lokalnych deklaracji zmiennych.

Możesz ograniczyć zakres dodatkowych zmiennych w metodach, używając takiego bloku:

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

Gwarantuje to, że nie przypadkowo ponownie użyjesz zmiennej w innym miejscu metody.

McDowell
źródło
10
Czy ktoś ma pojęcie, dlaczego projektanci języka wdrożyli to pozornie niepotrzebne ograniczenie?
Jeff Axelrod
@glenviewjeff - to najlepiej zadać jako osobne pytanie.
McDowell
2
@JeffAxelrod, być może ze względów historycznych, ponieważ Java była wzorowana na C ++ ... zobacz ten post: stackoverflow.com/questions/2687392/…
Christophe Roussy
3
+1 za użycie klocka, używam ich dużo, wciąż lepiej niż robienie głupich błędów
Christophe Roussy.
18

Nie możesz tego lubić. Albo używasz wielu zmiennych tego samego typu, for(Object var1 = null, var2 = null; ...)albo wyodrębniasz inną zmienną i deklarujesz ją przed pętlą for.

Colin Hebert
źródło
9

Po prostu przenieś deklaracje zmiennych ( Node<T> current, int currentIndex) poza pętlę i powinno działać. Coś takiego

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

a może nawet

int currentIndex;
for (Node<T> current = first; current != null; current = current.next, currentIndex++) {
Nikita Rybak
źródło
1
Żadne się nie skompiluje: musisz zainicjować zmienne przed użyciem.
unbeli
@unbeli cóż, nie ćwiczyłem w ręcznej kompilacji kodu :) Chciałem tylko dać pomysł.
Nikita Rybak
3
@unbeli: Żeby wyjaśnić: należy zainicjować currentIndex. Pierwszą rzeczą, jaką robi Nikita, jest „currentIndex ++”, co w naturalny sposób wywołuje pytanie, co zwiększyć? current jest w porządku, ponieważ pierwsze użycie polega na ustawieniu go jako pierwszego.
Jay
Zwykle, aby lepiej napisać inkrementację w pętli for, należy użyć ++ var jako notacji var ++ wymaganej od kompilatora do zduplikowania zawartości zmiennej przed jej zwiększeniem w celu zwrócenia jej jako wyniku wyrażenia, chociaż nikt nigdy tego nie chce. Oczywiście kompilator zoptymalizuje to, ale jest to jak wyrzucanie śmieci na drogę, czekając, aż inni posprzątają.
Chucky,
5

Zmienne zadeklarowane w bloku inicjalizacji muszą być tego samego typu

nie możemy zainicjować różnych typów danych w pętli for zgodnie z ich projektem. Podaję tylko mały przykład.

for(int i=0, b=0, c=0, d=0....;/*condition to be applied */;/*increment or other logic*/){
      //Your Code goes here
}
Vishnu Prasanth G.
źródło