[英]How to change value of ArrayList element in 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未更新。
该列表维护对列表中存储的原始值的对象引用。 所以当你执行这一行时:
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() ;//更改了List中frist元素的值
if(i.hasNext()){
i.next();
i.set(Integer.valueOf(9)); //更改迭代器当前所在的元素
}//新的迭代器,并打印所有元素
Iterator iter = a.iterator();
而(iter.hasNext())
是System.out.print(iter.next());>> 912345678
遗憾的是,同样不能扩展到Set <T>等其他集合。 实现细节(例如,哈希集实现为哈希表并更改对象可以更改哈希值,因此更改迭代顺序)使Set <T>成为“仅添加新/删除”类型的数据结构,并更改内容在迭代它时根本不安全。
您正在尝试更改列表中的值,但您所做的只是更改x的引用。 执行以下操作仅更改x,而不是集合中的任何内容:
x = Integer.valueOf(9);
此外, Integer
是不可变的,这意味着您无法更改Integer对象内的值(无论如何都需要使用不同的方法)。 这意味着您需要替换整个对象。 使用Iterator
无法做到这一点(不添加自己的拳击层)。 请执行以下操作:
a.set(0, 9);
我同意Duncan ...我用可变对象尝试了它但仍然遇到同样的问题...我得到了一个简单的解决方案...使用ListIterator而不是Iterator并使用ListIterator的set方法
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());
但是这限制了我只将它用于只能使用ListIterator的ArrayList ...我将与任何其他Collection有相同的问题
我认为问题是你认为声明......
x = Integer.valueOf(9);
...导致'9'的值被'存储'到(!)x引用的对象中。
但那错了。
相反,该语句会产生类似于您调用的类似内容
x = new Integer(9);
如果您查看java源代码,您将看到详细信息中会发生什么。
以下是“Integer”类中“valueOf(int i)”方法的代码:
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类时,都会调用以下脚本:
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++);
}
您会看到在valueOf方法中使用“new Integer(i)”创建新的Integer对象......或者返回存储在IntegerCache中的对整数对象的引用。
在这两种情况下,x都将引用一个新的Object。
这就是为什么当你打电话时,列表中对象的引用会丢失的原因...
x = Integer.valueOf(9);
而不是这样做,与ListIterator结合使用......
i.set(Integer.valueOf(9));
...在你得到你要改变的元素之后......
i.next();
将其更改为for(int i=0;i<=9;i++)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.