How to change value of ArrayList element in java

前端 未结 7 1854
清酒与你
清酒与你 2020-12-02 09:57

Please help me with below code , I get the same output even after changing the value

import java.util.*;

class Test {
    public static void main(String[] a         


        
相关标签:
7条回答
  • 2020-12-02 10:12

    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();
    
    0 讨论(0)
  • 2020-12-02 10:14

    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

    0 讨论(0)
  • 2020-12-02 10:24

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

    0 讨论(0)
  • 2020-12-02 10:25

    Use the set method to replace the old value with a new one.

    list.set( 2, "New" );
    
    0 讨论(0)
  • 2020-12-02 10:30

    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);
    
    0 讨论(0)
  • 2020-12-02 10:31

    The list is maintaining an object reference to the original value stored in the list. So when you execute this line:

    Integer x = i.next();
    

    Both x and the list are storing a reference to the same object. However, when you execute:

    x = Integer.valueOf(9);
    

    nothing has changed in the list, but x is now storing a reference to a different object. The list has not changed. You need to use some of the list manipulation methods, such as

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

    Note: this has nothing to do with the immutability of Integer, as others are suggesting. This is just basic Java object reference behaviour.


    Here's a complete example, to help explain the point. Note that this makes use of the ListIterator class, which supports removing/setting items mid-iteration:

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

    This will print:

    [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]
    
    0 讨论(0)
提交回复
热议问题