W przypadku poniższego kodu miałem nadzieję, że elementy mojej listy aranżacyjnej zostaną zmodyfikowane, ale tak nie jest. Jak mogę modyfikować elementy

public class Main {
    public static void main(String args[]){
        ArrayList<String> aList = new ArrayList<>();
        aList .add("aa");
        aList .add("bb");
        aList .add("cc");

        new Main().modifyList(aList );
        for(String s: aList ){
            System.out.println(s);
        }
    }

    public void modifyList(ArrayList<String> aList ){
        for(String s: aList){
            System.out.println(s);
            s = s + "ss";
        }
    }
}

Jego drukowanie aa bb cc aa bb cc

Oczekiwany wynik aa bb cc aass bbss ccss

0
Sudhik 4 kwiecień 2020, 00:32

4 odpowiedzi

Najlepsza odpowiedź
public void modifyList(ArrayList<String> aList ){
        for(String s: aList){
            System.out.println(s);
            s = s + "ss";
        }
    }

Ciągi znaków są niezmienne. Więc kiedy zmieniasz s, tworzysz nowy obiekt, który różni się od tego w ArrayList.

Musisz więc iterować po tablicy i zastąpić starą wartość nową, używając metody set.

for (int i = 0; i < alist.size(); i++) {
     String s = aList.get(i) + "ss";
     aList.set(i, s);
}

Aby po prostu dołączyć zmiany, wykonaj następujące czynności:

int len = alist.size();
for (int i = 0; i < len; i++) {
     String s = aList.get(i) + "ss";
     aList.add(s);
}

Wydruki

aa bb cc aass bbss ccss

1
WJS 3 kwiecień 2020, 21:48

Aby rozwiązać ten problem, musisz zaktualizować każdy element w następujący sposób:

public void modifyList(ArrayList<String> aList){
        for(int i = 0; i < aList.size(); i++){
            String s = aList.get(i);
            aList.set(i, s+"ss");
        }
}
0
Majed Badawi 3 kwiecień 2020, 21:35

s = s + "ss" aktualizuje tylko zmienną lokalną s, nie aktualizuje listy.

Jeśli chcesz zaktualizować elementy na liście, użyj ListIterator i set() metoda:

public static void modifyList(List<String> aList) {
    for (ListIterator<String> iter = aList.listIterator(); iter.hasNext(); ) {
        String s = iter.next();
        s = s + "ss";
        iter.set(s); // replace element in the list with new value
    }
}

W Javie 8+ możesz użyć wyrażenia lambda z replaceAll() metoda:

public static void modifyList(List<String> aList) {
    aList.replaceAll(s -> s + "ss");
}

Oba będą działać dobrze, nawet jeśli lista nie obsługuje dobrze dostępu swobodnego, np. jeśli lista to LinkedList.

Testuj

public static void main(String[] args) {
    List<String> aList = new ArrayList<>(Arrays.asList("aa", "bb", "cc"));
    modifyList(aList);
    System.out.println(aList);
}

Wyjście

[aass, bbss, ccss]
1
Andreas 3 kwiecień 2020, 21:46

Oto problem, zmienna s jest nieużywana i widoczna tylko w zakresie pętli for:

for (String s: aList) {
    System.out.println(s);
    s = s + "ss";           // the variable 's' is unused
}

Użyj List::set, aby zastąpić bieżącą wartość:

for (int i=0; i<aList.size(); i++) {
    String s = aList.get(i);
    System.out.println(s);
    aList.set(i, s + "ss");
}

... lub skorzystaj z zalet na dzień i zmapuj listę na nową:

List<String> newList = aList.stream()
                            .map(s -> s + "ss")
                            .collect(Collectors.toList());
1
Nikolas Charalambidis 3 kwiecień 2020, 21:41