Подтвердить что ты не робот

Как изменить значение элемента ArrayList в java

Пожалуйста, помогите мне с кодом ниже, я получаю тот же вывод даже после изменения значения

import java.util.*;

class Test {
    public static void main(String[] args) {
        ArrayList<Integer> a = new ArrayList<Integer>();

       // added 0-9 to ArrayList        
          for(int i=0;i<9;i++)
            a.add(new Integer(i));

        // initialize the Iterator
        Iterator<Integer> i = a.iterator();

        // changed the value of first element in List
        if(i.hasNext()) {
            Integer x = i.next();
            x = Integer.valueOf(9);
        }

        // initialized the iterator again and print all the elements
        i = a.iterator();
        while(i.hasNext())
            System.out.print(i.next());
    }
}    

//Output : 012345678

Значение 9 не обновляется.

4b9b3361

Ответ 1

Список поддерживает ссылку на объект на исходное значение, хранящееся в списке. Поэтому, когда вы выполняете эту строку:

Integer x = i.next();

Оба x и список сохраняют ссылку на тот же объект. Однако при выполнении:

x = Integer.valueOf(9);

ничего не изменилось в списке, но x теперь сохраняет ссылку на другой объект. Список не изменился. Вам нужно использовать некоторые из методов манипулирования списком, например

list.set(index, Integer.valueof(9))

Примечание: это не имеет никакого отношения к неизменности Integer, как предлагают другие. Это просто базовое поведение ссылки на объекты Java.


Вот полный пример, чтобы объяснить смысл. Обратите внимание, что это использует класс ListIterator, который поддерживает удаление/установку элементов средней итерации:

import java.util.*;

public class ListExample {

  public static void main(String[] args) {

    List<Foo> fooList = new ArrayList<Foo>();
    for (int i = 0; i < 9; i++)
      fooList.add(new Foo(i, i));

    // Standard iterator sufficient for altering elements
    Iterator<Foo> iterator = fooList.iterator();

    if (iterator.hasNext()) {
      Foo foo = iterator.next();
      foo.x = 99;
      foo.y = 42;
    }

    printList(fooList);    

    // List iterator needed for replacing elements
    ListIterator<Foo> listIterator = fooList.listIterator();

    if (listIterator.hasNext()) {
      // Need to call next, before set.
      listIterator.next();
      // Replace item returned from next()
      listIterator.set(new Foo(99,99));
    }

    printList(fooList);
  }

  private static void printList(List<?> list) {
    Iterator<?> iterator = list.iterator();
    while (iterator.hasNext()) {
      System.out.print(iterator.next());
    }
    System.out.println();
  }

  private static class Foo {
    int x;
    int y;

    Foo(int x, int y) {
      this.x = x;
      this.y = y;
    }

    @Override
    public String toString() {
      return String.format("[%d, %d]", x, y);
    }
  }
}

Это напечатает:

[99, 42][1, 1][2, 2][3, 3][4, 4][5, 5][6, 6][7, 7][8, 8]
[99, 99][1, 1][2, 2][3, 3][4, 4][5, 5][6, 6][7, 7][8, 8]

Ответ 2

Где вы говорите, что вы меняете значение первого элемента;

x = Integer.valueOf(9);

Вы меняете x, чтобы указать на совершенно новый Integer, но никогда не используете его снова. Вы никоим образом не меняете коллекцию.

Поскольку вы работаете с ArrayList, вы можете использовать ListIterator, если хотите, чтобы итератор позволял вам изменять элементы, это фрагмент кода, который нужно изменить;

//инициализировать Iterator
ListIterator <Integer> я = a. listIterator();

//изменил значение элемента frist в списке
if (i.hasNext()) {     i.next();
    i.set(Integer.valueOf(9));    //Изменить элемент, на котором итератор в настоящее время находится на
}

//Новый итератор и напечатать все элементы
Итератор iter = a.iterator();
в то время как (iter.hasNext)()
    System.out.print(iter.next());

→ 912345678

К сожалению, то же самое нельзя распространить на другие коллекции, такие как Set <T> . Детали реализации (например, HashSet, реализуемый как хеш-таблица и изменяющий объект, может изменять хеш-значение и, следовательно, порядок итерации) делает Set <T> структурой данных "добавить новый/удаленный" и изменяет содержимое в то время как итерация по ней небезопасна.

Ответ 3

Используйте метод set для замены старого значения на новый.

list.set( 2, "New" );

Ответ 4

Вы пытаетесь изменить значение в списке, но все, что вы делаете, это изменение ссылки на x. Выполнение следующих изменений: x, а не что-либо в коллекции:

x = Integer.valueOf(9);

Кроме того, Integer является неизменным, что означает, что вы не можете изменить значение внутри объекта Integer (что в любом случае потребует другого метода). Это означает, что вам нужно заменить весь объект. Невозможно сделать это с помощью Iterator (без добавления собственного слоя бокса). Вместо этого сделайте следующее:

a.set(0, 9);

Ответ 5

Я согласен с Duncan... Я пробовал его с изменяемым объектом, но все равно получаю ту же проблему... Я получил простое решение для этого... используйте ListIterator вместо Iterator и используйте метод set ListIterator

ListIterator<Integer> i = a.listIterator();
//changed the value of first element in List
Integer x =null;
        if(i.hasNext()) {
            x = i.next();
            x = Integer.valueOf(9);
        }
    //set method sets the recent iterated element in ArrayList
    i.set(x);
        //initialized the iterator again and print all the elements
        i = a.listIterator();
        while(i.hasNext())
        System.out.print(i.next());

Но это ограничивает меня использованием этого только для ArrayList, который может использовать ListIterator... У меня будет такая же проблема с любой другой коллекцией

Ответ 6

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

x = Integer.valueOf(9);

... вызывает, что значение "9" получает "хранится" в (!) объекте, на который ссылается х.

Но это неправильно.

Вместо этого оператор вызывает нечто похожее, как если бы вы звонили

x = new Integer(9); 

Если вы посмотрите на исходный код java, вы увидите, что происходит в деталях.

Вот код метода valueOf (int i) в классе Integer:

public static Integer valueOf(int i) {
    assert IntegerCache.high >= 127;
    if (i >= IntegerCache.low && i <= IntegerCache.high)
        return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);
}

и далее, всякий раз, когда класс IntegerCache используется в первый раз, вызывается следующий script:

static {
        // high value may be configured by property
        int h = 127;
        String integerCacheHighPropValue =
            sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
        if (integerCacheHighPropValue != null) {
            int i = parseInt(integerCacheHighPropValue);
            i = Math.max(i, 127);
            // Maximum array size is Integer.MAX_VALUE
            h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
        }
        high = h;

        cache = new Integer[(high - low) + 1];
        int j = low;
        for(int k = 0; k < cache.length; k++)
            cache[k] = new Integer(j++);
    }

Вы видите, что либо новый объект Integer создается с помощью "нового Integer (i)" в методе valueOf... ... или возвращается ссылка на объект Integer, который хранится в IntegerCache.

В обоих случаях x будет ссылаться на новый объект.

И вот почему ссылка на объект в вашем списке теряется при вызове...

x = Integer.valueOf(9);

Вместо этого в сочетании с использованием ListIterator...

i.set(Integer.valueOf(9));

... после того, как вы получили элемент, который хотите изменить с помощью...

i.next();

Ответ 7

Измените его на for(int i=0;i<=9;i++)