2013-01-03 10 views
5

Chciałbym wiedzieć szczegółowo, jak działa Enhanced For Loop w Javie (zakładając, że rozumiem, jak podstawowe jest użycie tej pętli i jak to działa w ogóle) .Java Enhanced For Loop - Edycja Oryginalnych Wartości Array

Biorąc pod uwagę następujący kod:

String[] a = {"dog", "cat", "turtle"}; 

for (String s : a) { 
    out.println("String: " + s); 
    s = in.readLine("New String? "); 
} 

To faktycznie nie modyfikowania oryginalnego listy 'a'. Dlaczego nie? Jak działa zarządzanie pamięcią? Czy nie jest "odniesieniem" do tej samej komórki pamięci "a [i]"?

Przeczytałem w dokumentacji Oracle, że rozszerzone na pętle nie mogą być używane do usuwania elementów z oryginalnej tablicy, ma to sens. Czy to samo dotyczy modyfikowania wartości?

góry dzięki

+3

Ciąg jest niezmienny. Http://stackoverflow.com/a/8798424/112500 – Shashi

+0

's' jest zmienną zawierającą odniesienie do elementu kontenera. –

Odpowiedz

10

nie 's' jest nawiązaniem do tej samej komórki pamięci 'a [i]'?

Oryginalnie tak. Ale wtedy in.readLine tworzy odniesienie do nowego obiektu String, który następnie można użyć do nadpisania s. Ale tylko s jest nadpisywany, a nie leżący pod nim łańcuch znaków ani odniesienie w tablicy.

+0

Wielkie dzięki, to było naprawdę pomocne. Teraz jest jasne. – jnardiello

+1

@Oliver, masz na myśli to, że referencja zaczyna się odsyłając do jakiegoś innego obiektu typu string, a nie [i] kiedy tak s = nowy ciąg ("X")? – Abhinav

+1

@Abrinow: Tak .. –

4

s to lokalna zmienna wskazująca na instancję String. Nie jest związane z a[i], po prostu mają one tę samą wartość początkowo.

3

Można pisać tylko

for (int i = 0; i < a.length; i++) { 
    out.println("String: " + a[i]); 
    a[i] = in.readLine("New String? "); 
} 

nie można używać pętli for-each zmodyfikować oryginalną kolekcję lub tablicę.

+0

Podałeś jasny ostatni punkt, który wciąż był rozmazany. Wielkie dzięki! – jnardiello

+1

Jeśli chcesz usunąć() lub zmienić pozycje dla listy, musisz jawnie użyć Iteratora. –

1

Pomyśl o s jak o adresie adres. Chodzi o to, że s wskazuje na pewną wartość tablicy podczas korzystania z pętli for. Po potwierdzeniu s w pętli jest po prostu przypadek, że s wskazuje na inną wartość, ale oryginalna wartość tablicy nie jest modyfikowana, ponieważ zmieniasz tylko adres.

String[] a = {"dog", "cat", "turtle"}; 

for (String s : a) { 
    //s --> "dog" 
    out.println("String: " + s); 
    s = in.readLine("New String? "); 
    //s --> the new string the user inputs 
} 
+1

Bardzo dziękuję za szczegółową odpowiedź. To, czego mi brakowało, to fakt, że readLine zwraca nowy adres. – jnardiello

+0

W przypadku odpowiedzi na pytanie, przekaż i przyjmij odpowiedź;) – Averroes

1

Dla każdej iteracji Ciąg początkowo odwołuje się do odpowiedniego obiektu String w łańcuchu a []. Ale odwołuje się do innego obiektu String, który jest zwracany przez in.readLine().