Итерация списка <String>с строкой модификации - PullRequest
6 голосов
/ 31 января 2011

Я не могу модифицировать элемент List следующим образом:

for (String s : list)
{
   s = "x" + s;
}

После выполнения этого кода элементы этого списка не изменяются. Как проще всего выполнить итерацию с модификацией через List.

Ответы [ 7 ]

13 голосов
/ 31 января 2011

Поскольку String объекты неизменны, вы не можете изменять значения, по которым вы перебираете.Кроме того, вы не можете изменить список, который вы повторяете в таком цикле.Единственный способ сделать это - перебрать индексы списка со стандартным циклом или использовать интерфейс ListIterator:

for (int i = 0; i < list.size(); i++)
{
    list.set(i, "x" + list.get(i));
}

for (ListIterator i = list.listIterator(); i.hasNext(); )
{
    i.set("x" + i.next());
}
3 голосов
/ 31 января 2011

Примерно так должно работать:

public static void main(String[] args) throws Exception {
    final List<String> lst = Arrays.asList("a", "b", "c");
    for(final ListIterator<String> iter = lst.listIterator(); iter.hasNext(); ) {
        final String s = iter.next();
        iter.set(s + "x");
    }
    System.out.println(lst);
}
3 голосов
/ 31 января 2011

Строки - это неизменные звери, поэтому я могу рекомендовать следовать этой философии и создать новый список вместо изменения одного:

List<String> mappedList = new ArrayList<String>();

for (String s : list) {
    mappedList.add("x" + s);
}

Я считаю, что это облегчит понимание и поддержку вашего кода.

2 голосов
/ 31 января 2011

Как уже отмечали другие:

  • Вы не можете изменять строки в Java, поэтому s = "x" + s создаст новую строку (которая не будет содержаться в списке)
  • Даже если бы вы могли, переменная s является локальной переменной, которая, когда присваивается, не влияет на значения, содержащиеся в списке.

В этом случае решение заключается в использованииStringBuilder, представляющий строку, которую вы можете фактически изменить, или использовать ListIterator, как указывает @Michael Borgwardt и @jarnbjo.


Использование StringBuilder:

List<StringBuilder> someStrings = new LinkedList<StringBuilder>();
someStrings.add(new StringBuilder("hello"));
someStrings.add(new StringBuilder("world"));

for (StringBuilder s : someStrings)
    s.insert(0, "x");

Использование ListIterator:

List<String> someStrings = new LinkedList<String>();
someStrings.add("hello");
someStrings.add("world");

for (ListIterator<String> iter = someStrings.listIterator(); iter.hasNext();)
    iter.set("x" + iter.next());

ideone.com demo

2 голосов
/ 31 января 2011

Java-строки неизменны, поэтому их нельзя изменить. Кроме того, если вы хотите изменить список, используйте интерфейс итератора.

1 голос
/ 31 января 2011

Вы не можете изменить String элемент List таким образом, но StringBuilder будет работать просто отлично:

for (StringBuilder sb : list) sb.append("x");

То же самое верно для других примитивов по сравнению с эталонными ситуациямии для каждого цикла.В цикле Iterable является неизменным, но состояние элементов в нем отсутствует - примитивы (например, String) не имеют состояния и, следовательно, вы изменяете только локальную копию, но ссылки могут иметь состояние и, следовательно,Вы можете изменить их с помощью любых методов-мутаторов (например, sb.append("x")).

1 голос
/ 31 января 2011

В вашем цикле вы просто изменяете локальную копию строки.Лучшая альтернатива - использовать итератор списка и заменить текущую позицию списка.

Изменить, К сожалению, способ замедления.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...