当前位置:编程学习 > JAVA >>

为什么list集合元素莫名其妙的被修改??

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class Demo {
/**
 * @param args
 */
public static void main(String[] args) {
List<List<String>> testlist = new ArrayList<List<String>>();

String[] items = { "lorem", "ipsum", "dolor", "purus" };

List<String> list1 = Arrays.asList(items);
System.out.println("原集合:"+list1.toString());
testlist.add(list1);

// 把集合的顺序打乱
Collections.shuffle(list1);
System.out.println("打乱后集合:"+list1.toString());
testlist.add(list1);

list1 = Arrays.asList(items);
Collections.shuffle(list1);
System.out.println("再次打乱后集合:"+list1.toString());
testlist.add(list1);

System.out.println(testlist.toString());

}

}


添加进去的元素是没有问题的,但是最后list集合所有元素只和最后一次添加进去的形同。不解,求大牛赐教!!!
--------------------编程问答-------------------- 自己debug下慢慢看,同一个对象搞来搞去。 --------------------编程问答-------------------- 因为你的testlist里面放的自始至终都是同一个对象
如果你想放不同的对象,请用类似下面这种
List<List<String>> testlist = new ArrayList<List<String>>();
String[] items = { "lorem", "ipsum", "dolor", "purus" };
for(int i = 0; i < 3; i++){
    List<String> list1 = Arrays.asList(items);
    Collections.shuffle(list1);
    testlist.add(list1);
}
对比一下你就能看出有什么不同 --------------------编程问答-------------------- 很简单的问题
首先,你的代码写的有问题,没有测试性
应该这样
List<List<String>> testlist = new ArrayList<List<String>>();

String[] items = { "lorem", "ipsum", "dolor", "purus" };

List<String> list1 = Arrays.asList(items);
System.out.println("原集合:" + list1.toString());
testlist.add(list1);

List<String> list2 = Arrays.asList(items);
Collections.shuffle(list2);
System.out.println("打乱后集合:" + list2.toString());
testlist.add(list2);

List<String> list3 = Arrays.asList(items);
Collections.shuffle(list3);
System.out.println("再次打乱后集合:" + list3.toString());
System.out.println(testlist);
然后,说说原因,Arrays.asList() 是将一个数组 变成一个arraylist返回,当然arraylist本身就是一个数组,所以产生的arraylist其实就是对数组重新包装了一下,所以list1,list2,list3底层对应的是一个数组,Collections.shuffle() 是打乱集合,打乱任意一个list,其他都变了,是不是?
Arrays.asList() 产生的Arraylist于java.util.Arraylist 其实不是一个类,看看代码
                System.out.println(list3.getClass());
System.out.println(new ArrayList<String>());
打印结果:
                class java.util.Arrays$ArrayList
                class java.util.ArrayList
所以看出来前者是后者的子类,对吧,你可以试试对前者进行更新操作,如删除,remove,add,看看会报什么错,想想为什么 --------------------编程问答--------------------
引用 2 楼 xiesisi3 的回复:
因为你的testlist里面放的自始至终都是同一个对象
如果你想放不同的对象,请用类似下面这种
List<List<String>> testlist = new ArrayList<List<String>>();
String[] items = { "lorem", "ipsum", "dolor", "purus" };
for(int i = 0; i ……

不是问题的症结所在
--------------------编程问答-------------------- 这好比把lz抓进监狱  第二天把lz拉出来打一顿在抓进监狱

其实结果还是只有一个人 --------------------编程问答--------------------
引用 5 楼 tianma630 的回复:
这好比把lz抓进监狱  第二天把lz拉出来打一顿在抓进监狱

其实结果还是只有一个人

==========================================
这个回答经典。楼主根本没有搞清楚对象是怎么引用的。
但是有一个,拉出来打一顿,不放回去也在里面,即:testlist.add(list1);
只要执行一次,后面两个不执行,也是最后一次结果。list1在内存中的地址只有一份,反复加结果一样。

其实一楼就说了问题所在,因为我之前也这样回答,可是别人看不懂,这里帮你解释一下原因。
list1在内存中的地址只有一份,只要是对它进行操作,所有地方都会改变。 --------------------编程问答--------------------
引用 6 楼 lizhengguang 的回复:
引用 5 楼 tianma630 的回复:这好比把lz抓进监狱  第二天把lz拉出来打一顿在抓进监狱

其实结果还是只有一个人
==========================================
这个回答经典。楼主根本没有搞清楚对象是怎么引用的。
但是有一个,拉出来打一顿,不放回去也在里面,即:testlist.add(list1);
只要执……

楼主的代码里面有两大问题,你只说中了一个 --------------------编程问答-------------------- 我觉得是这样吧,你虽然把list2打乱了,但是你并没有把打乱后的list2重新赋值给list2,所以list2没有变化,那你添加list2的时候就还是原集合的样子 --------------------编程问答-------------------- debug --------------------编程问答-------------------- 又仔细看了一下,不是和最后一次添加进去的形同,而是和你最后一次打乱的list形同,如果你的List3不打乱,只打乱List2的话,那就和list2相同了。因为list1的地址始终没有改变,都是同一个对象。你打乱的时候把list1打乱了,但是你往testlist里添加的时候,testlist里面的3个空间都是指向同一个地址的,所以打乱了也是3个保持一致,永远跟你最后一次打乱相同 --------------------编程问答--------------------
List<List<String>> testlist = new ArrayList<List<String>>();

String[] items = { "lorem", "ipsum", "dolor", "purus" };

List<String> list1 = Arrays.asList(items);
System.out.println("原集合:"+list1.toString());
testlist.add(list1);

// 把集合的顺序打乱
List<String> list2 = new ArrayList<String>();
for(String i:items){
list2.add(i);
}
Collections.shuffle(list2);
System.out.println("打乱后集合:"+list2.toString());
testlist.add(list2);

List<String> list3 = new ArrayList<String>();
for(String i:items){
list3.add(i);
}
Collections.shuffle(list3);
System.out.println("再次打乱后集合:"+list3.toString());
testlist.add(list3);

System.out.println(testlist.toString());
--------------------编程问答--------------------
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class Demo {
/**
 * @param args
 */
public static void main(String[] args) {

List<List<String>> testlist = new ArrayList<List<String>>();
String[] items = { "lorem", "ipsum", "dolor", "purus" };
List<String> list1 = Arrays.asList(items);
List<String> list2;
List<String> list3;
testlist.add(list1);
System.out.println(list1);
Collections.shuffle(list1);
System.out.println(list1);
list2 = list1;
testlist.add(list2);
System.out.println(list2);
Collections.shuffle(list2);
System.out.println(list2);
list3 = list2;
testlist.add(list3);
System.out.println(testlist.toString());
}

}
 即时是拥有三个不同引用 调用add()方法之后依旧存在这个问题 求大神解决 --------------------编程问答--------------------
引用 12 楼 wuyanxue 的回复:
Java code?12345678910111213141516171819202122232425262728293031import java.util.ArrayList;import java.util.Arrays;import java.util.Collections;import java.util.List; public class Demo {/*……
我在上面不是给你解释了么?
--------------------编程问答-------------------- 谢谢楼主的分享 --------------------编程问答--------------------
引用 12 楼 wuyanxue 的回复:
Java code?12345678910111213141516171819202122232425262728293031import java.util.ArrayList;import java.util.Arrays;import java.util.Collections;import java.util.List; public class Demo {/*……


你这跟楼主的问题不是一样吗,哪有三个引用啊,这3个list都是list1 --------------------编程问答-------------------- “即使是使用了三种不同的引用……”,你自己也说了是引用,也就是换个名字而已,实质还是一个对象。

你每次对这个对象的操作,都会改变这个对象的状态,这就好比一瓶450ML的可乐,第一口喝掉50ML,第二口喝掉40ML,第三口喝掉50ML,这时我们把剩余的可能倒入碗中,倒了多少呢,肯定是最后一口喝剩下的,此时第一口喝剩下的还有意义吗?

你要的效果可以做如下修改:
public class Demo {
/**
 * @param args
 */
public static void main(String[] args) {
List<List<String>> testlist = new ArrayList<List<String>>();

String[] items = { "lorem", "ipsum", "dolor", "purus" };

List<String> list1 = new ArrayList(Arrays.asList(items));
System.out.println("原集合:" + list1.toString());
testlist.add(list1);

// 把集合的顺序打乱
List<String> list2 = new ArrayList(Arrays.asList(items));
Collections.shuffle(list2);
System.out.println("打乱后集合:" + list2.toString());
testlist.add(list2);

List<String> list3 = new ArrayList(Arrays.asList(items));
Collections.shuffle(list3);
System.out.println("再次打乱后集合:" + list3.toString());
testlist.add(list3);

System.out.println(testlist.toString());

}

} --------------------编程问答--------------------
引用 16 楼 xsd219222 的回复:
“即使是使用了三种不同的引用……”,你自己也说了是引用,也就是换个名字而已,实质还是一个对象。

你每次对这个对象的操作,都会改变这个对象的状态,这就好比一瓶450ML的可乐,第一口喝掉50ML,第二口喝掉40ML,第三口喝掉50ML,这时我们把剩余的可能倒入碗中,倒了多少呢,肯定是最后一口喝剩下的,此时第一口喝剩下的还有意义吗?

你要的效果可以做如下修改:
……
菜鸟
--------------------编程问答-------------------- 我好像懂了一点 --------------------编程问答--------------------
引用 17 楼 xie709955748 的回复:

是菜鸟,但在努力学习中。
楼主也可以把add换成addAll,那样是把list1里面的每个元素放入testlist,后面对list1操作就不会影响到了。
testlist.addAll(list);//把list中的每一个元素加到result中,testlist.size()==list.size()
testlist.add(list);//将list作为一个元素加到result中,则testlist.size()为1

public class Demo {
/**
 * @param args
 */
public static void main(String []args) {
List<String> testlist = new ArrayList<String>();

String[] items = { "lorem", "ipsum", "dolor", "purus" };

List<String> list1 = Arrays.asList(items);
System.out.println("原集合:" + list1.toString());
testlist.addAll(list1);

List<String> list2 = Arrays.asList(items);
Collections.shuffle(list2);
System.out.println("打乱后集合:" + list2.toString());
testlist.addAll(list2);

List<String> list3 = Arrays.asList(items);
Collections.shuffle(list3);
testlist.addAll(list3);

System.out.println("再次打乱后集合:" + list3.toString());
System.out.println(testlist);
    }

}
--------------------编程问答--------------------
引用 3 楼 xie709955748 的回复:
很简单的问题
首先,你的代码写的有问题,没有测试性
应该这样
List<List<String>> testlist = new ArrayList<List<String>>();

String[] items = { "lorem", "ipsum", "dolor", "purus" };

List<String> list1 = Arrays.a……


答非所问,地址引用,老生常谈 --------------------编程问答--------------------
引用 20 楼 yizishaonian 的回复:
引用 3 楼 xie709955748 的回复:很简单的问题
首先,你的代码写的有问题,没有测试性
应该这样
List<List<String>> testlist = new ArrayList<List<String>>();

String[] items = { "lorem", "ipsum", "dolor", "purus" };

List<……
呵呵,你有仔细跑过楼主的代码,然后再改成对的在跑过么?地址应用只是最外面的问题,即使使用三个list,也是不行的,涉及到Arraylist的底层实现
--------------------编程问答-------------------- 除
补充:Java ,  Java SE
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,