为何修改外部int[]变量会改变ArrayList<int[]>中的数组?如何解决?
问题解析与解决方案
为什么集合中的数组会随原数组修改而变化?
Java中数组属于引用类型,当你调用arr.add(variables)时,ArrayList存储的并不是数组的副本,而是指向variables数组在堆内存中地址的引用。也就是说,集合里的元素和variables变量指向的是同一个数组对象。当你修改variables数组的元素时,本质是修改堆内存中那个数组对象的内容,集合通过引用访问到的自然也是修改后的内容。
超大数组的高效解决方案
直接创建新数组手动赋值确实不适合超大数组,推荐使用Java提供的高效数组拷贝方法,这些方法底层都是优化过的本地实现,性能远高于手动循环赋值:
1. 使用Arrays.copyOf()
这是最简洁的方式,底层调用System.arraycopy(),适合快速生成原数组的副本:
import java.util.*; public class test2 { public static void main (String[] args) { ArrayList<int[]> arr = new ArrayList<>(); int[] variables = {10, 20}; // 拷贝数组后添加到集合 arr.add(Arrays.copyOf(variables, variables.length)); System.out.println(arr.get(0)[0] + " " + arr.get(0)[1]); // 输出: 10 20 // 修改原数组 variables[0] = 0; variables[1] = 5; // 集合中的数组不受影响 System.out.println(arr.get(0)[0] + " " + arr.get(0)[1]); // 输出: 10 20 } }
2. 使用System.arraycopy()
如果需要更灵活的拷贝(比如只拷贝数组的一部分),可以直接用这个本地方法,性能最优:
import java.util.*; public class test2 { public static void main (String[] args) { ArrayList<int[]> arr = new ArrayList<>(); int[] variables = {10, 20}; // 创建新数组,长度和原数组一致 int[] copy = new int[variables.length]; // 拷贝原数组内容到新数组 System.arraycopy(variables, 0, copy, 0, variables.length); arr.add(copy); // 后续修改原数组不会影响集合中的copy数组 variables[0] = 0; System.out.println(arr.get(0)[0]); // 输出: 10 } }
注意事项
- 这两种方法都是浅拷贝,对于一维
int[]来说完全够用(因为int是基本类型);如果是引用类型数组(比如String[]或自定义对象数组),需要根据需求考虑深拷贝,但你的场景不需要。 - 对于超大数组,创建新数组的内存开销是保证集合元素独立的必要代价,而这两种方法的拷贝效率是Java中最高的。
内容的提问来源于stack exchange,提问作者Szyxth
相关产品推荐
相关产品推荐

