向二维ArrayList两次添加不同内容的同一ArrayList为何内容重复?
问题原因分析
你遇到的问题核心是Java中ArrayList属于引用类型,而非值类型。当你把sList添加到wList时,存入的并不是sList的“副本”,而是指向这个ArrayList对象的内存引用。
具体到你的代码执行流程:
- 初始化sList并添加"1"、"2",此时sList指向内存中的一个ArrayList对象A,内容是
["1","2"]。 - 将sList添加到wList,wList的第一个元素保存的是对象A的引用,此时wList内容是
[[1,2]]。 - 调用
sList.clear()和sList.add("3"),这是直接修改对象A的内容,把它改成了["3"]。因为wList的第一个元素引用的还是对象A,所以它的内容也同步变成了["3"]。 - 再次将sList添加到wList,只是把对象A的引用又存入了wList的第二个位置。现在wList的两个元素都指向同一个对象A,所以打印出来的内容自然完全相同。
解决方案
有两种常用的解决方式:
方式1:每次添加前创建新的ArrayList对象
不要复用同一个sList,每次需要添加新列表时,重新实例化一个ArrayList:
package fc; import java.util.ArrayList; public class AppendList03 { public static void main(String[] args) { ArrayList<ArrayList<String>> wList = new ArrayList<ArrayList<String>>(); ArrayList<String> sList = new ArrayList<String>(); sList.add("1"); sList.add("2"); System.out.println(sList); wList.add(sList); System.out.println(wList); // 重新创建新的ArrayList对象,而非修改原对象 sList = new ArrayList<>(); sList.add("3"); wList.add(sList); System.out.println(wList); } }
方式2:添加时传入原列表的副本
如果需要保留原sList的内容,可以在添加时创建一个原列表的副本存入wList:
package fc; import java.util.ArrayList; public class AppendList03 { public static void main(String[] args) { ArrayList<ArrayList<String>> wList = new ArrayList<ArrayList<String>>(); ArrayList<String> sList = new ArrayList<String>(); sList.add("1"); sList.add("2"); System.out.println(sList); // 添加sList的副本到wList wList.add(new ArrayList<>(sList)); System.out.println(wList); sList.clear(); sList.add("3"); // 再次添加副本 wList.add(new ArrayList<>(sList)); System.out.println(wList); } }
内容的提问来源于stack exchange,提问作者Frankie Chiu
相关产品推荐
相关产品推荐

