如何在java中更改ArrayList元素的值
请帮助我下面的代码,我得到相同的输出,即使在改变值如何在java中更改ArrayList元素的值,java,arraylist,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++)
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
import java.util.*;
课堂测试{
公共静态void main(字符串[]args){
ArrayList a=新的ArrayList();
//将0-9添加到ArrayList
对于(inti=0;i,您说您正在更改第一个元素的值
x = Integer.valueOf(9);
您正在更改x
以指向一个全新的整数,但不再使用它。您不会以任何方式更改集合
由于您使用的是ArrayList,如果您想要一个允许您更改元素的迭代器,那么可以使用ListIterator,这是需要更改的代码片段
//初始化迭代器
ListIteratori=a.ListIterator()
//更改了列表中第一个元素的值
如果(i.hasNext()){
i.next();
i.set(Integer.valueOf(9));//更改迭代器当前所在的元素
}
//新建迭代器,并打印所有元素
迭代器iter=a.Iterator();
而(iter.hasNext())
System.out.print(iter.next())
>>912345678
遗憾的是,这一点不能扩展到其他集合,如Set。实现细节(例如,将HashSet实现为哈希表并更改对象可能会更改哈希值,从而更改迭代顺序)使Set成为“仅添加新/删除”数据结构的类型,并且在迭代时更改内容是不安全的。您试图更改列表中的值,但所做的只是更改x的引用。执行以下操作仅更改x,而不更改集合中的任何内容:
x = Integer.valueOf(9);
此外,Integer
是不可变的,这意味着您不能更改Integer对象内的值(这需要使用不同的方法)。这意味着您需要替换整个对象。使用迭代器(不添加自己的装箱层)无法做到这一点。请改为执行以下操作:
a.set(0, 9);
列表正在维护对列表中存储的原始值的对象引用。因此,当执行此行时:
Integer x = i.next();
x
和列表都存储了对同一对象的引用。但是,执行时:
x = Integer.valueOf(9);
列表中没有任何更改,但是x
正在存储对其他对象的引用。列表没有更改。您需要使用一些列表操作方法,例如
list.set(index, Integer.valueof(9))
注意:正如其他人所建议的,这与Integer
的不变性无关。这只是基本的Java对象引用行为
下面是一个完整的示例,有助于解释这一点。请注意,这使用了支持在迭代过程中删除/设置项的类:
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);
}
}
}
我同意邓肯的观点…我用可变对象尝试过,但仍然遇到同样的问题。。。
我得到了一个简单的解决方案…使用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 i=a.ListIterator();
//更改了列表中第一个元素的值
整数x=null;
if(i.hasNext()){
x=i.next();
x=整数。值为(9);
}
//set方法在ArrayList中设置最近迭代的元素
i、 组(x);
//再次初始化迭代器并打印所有元素
i=a.listIterator();
while(i.hasNext())
System.out.print(i.next());
但是这限制了我只对可以使用ListIterator的ArrayList使用它…我对任何其他集合都会有相同的问题我认为问题在于您认为该语句
x = Integer.valueOf(9);
…导致“9”的值“存储”到x所引用的对象(!)中
但这是错误的
相反,该语句会导致类似于您将调用
x = new Integer(9);
如果您查看一下java源代码,您将看到详细的情况
下面是“Integer”类中“valueOf(int i)”方法的代码:
与其这样做,不如结合ListIterator使用
i.set(Integer.valueOf(9));
…在获得要更改的元素后
i.next();
将其更改为for(int i=0;i使用set方法将旧值替换为新值
list.set( 2, "New" );
Integer
的不变性是不相关的。@DuncanJones不,实际上不是。如果Integer
是可变的,那么可能存在一种方法,如saychangeValue(int)
。但是,由于它是不可变的,我们知道这样的方法不存在。很好,但我担心这不会影响代码示例不起作用的原因。即使使用可变类,代码也不会像OP期望的那样执行-试试吧。正如我在回答的第一句中已经解释的那样“您试图更改列表中的值,但您所做的只是更改x的引用。”我理解。我不是说答案不正确(因此没有否决票)。我只是建议您在与问题无关的情况下提及不变性可能会混淆问题。那么如何做到这一点……我如何更改集合?@Prateksarda添加了您的示例在ListIterator中的外观。@Prateksarda添加了一些有关迭代Set
的信息。Iterator似乎没有集合()方法,因为返回错误:“类型迭代器的方法集(Float)未定义”。如果您考虑Integer,这可以正常工作,但如果我使用任何其他对象,请执行以下场景1)具有两个字段x和y的TempClass 2)在ArraryList a.add(新TempClass)中存储一些对象@prateeksarda请参见问题中添加的示例。我怀疑您真正想要的是ListIterator
类。我在上面提供了一个示例。ListIterator工作正常,正如我所想,但它将我限制在ArrayList集合中。如果我使用任何其他集合(如SetNote),该怎么办:这与immutabi无关
x = Integer.valueOf(9);
i.set(Integer.valueOf(9));
i.next();
list.set( 2, "New" );