Programing

Java에서 ArrayList 요소의 값을 변경하는 방법

lottogame 2020. 11. 18. 08:20
반응형

Java에서 ArrayList 요소의 값을 변경하는 방법


아래 코드로 도와주세요. 값을 변경 한 후에도 동일한 출력을 얻습니다.

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가 업데이트되지 않습니다.


목록은 목록에 저장된 원래 값에 대한 개체 참조를 유지합니다. 따라서이 줄을 실행할 때 :

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]

set 메서드를 사용하여 이전 값을 새 값으로 바꿉니다.

list.set( 2, "New" );

첫 번째 요소의 값을 변경한다고 말하는 곳;

x = Integer.valueOf(9);

x완전히 새로운 정수를 가리 키도록 변경 하지만 다시 사용하지 않습니다. 어떤 식 으로든 컬렉션을 변경하지 않습니다.

ArrayList로 작업하고 있기 때문에 요소 변경할 수있는 반복기를 원할 경우 ListIterator를 사용할 수 있습니다 . 이것은 변경해야하는 코드 스 니펫입니다.

// 반복기 초기화
ListIterator <Integer> i = a. listIterator () ;

//changed the value of frist element in List
if(i.hasNext()) {
    i.next();
    i.set(Integer.valueOf(9));    // Change the element the iterator is currently at
}

// New iterator, and print all the elements
Iterator iter = a.iterator();
while(iter.hasNext())
    System.out.print(iter.next());

>> 912345678

Sadly the same cannot be extended to other collections like Set<T>. Implementation details (a HashSet for example being implemented as a hash table and changing the object could change the hash value and therefore the iteration order) makes Set<T> a "add new/remove only" type of data structure, and changing the content at all while iterating over it is not safe.


You're trying to change the value in the list, but all you're doing is changing the reference of x. Doing the following only changes x, not anything in the collection:

x = Integer.valueOf(9);

Additionally, Integer is immutable, meaning you can't change the value inside the Integer object (which would require a different method to do anyway). This means you need to replace the whole object. There is no way to do this with an Iterator (without adding your own layer of boxing). Do the following instead:

a.set(0, 9);

I agree with Duncan ...I have tried it with mutable object but still get the same problem... I got a simple solution to this... use ListIterator instead Iterator and use set method of 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());

But this constraints me to use this only for ArrayList only which can use ListIterator...i will have same problem with any other Collection


I think the problem is that you think the statement ...

x = Integer.valueOf(9);

... causes that the value of '9' get 'stored' into(!) the Object on which x is referencing.

But thats wrong.

Instead the statement causes something similar as if you would call

x = new Integer(9); 

If you have a look to the java source code, you will see what happens in Detail.

Here is the code of the "valueOf(int i)" method in the "Integer" class:

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);
}

and further, whenever the IntegerCache class is used for the first time the following script gets invoked:

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++);
    }

You see that either a new Integer Object is created with "new Integer(i)" in the valueOf method ... ... or a reference to a Integer Object which is stored in the IntegerCache is returned.

In both cases x will reference to a new Object.

And this is why the reference to the Object in your list get lost when you call ...

x = Integer.valueOf(9);

Instead of doing so, in combination with a ListIterator use ...

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

... after you got the element you want to change with ...

i.next();

Change it to for(int i=0;i<=9;i++)

참고URL : https://stackoverflow.com/questions/12772443/how-to-change-value-of-arraylist-element-in-java

반응형