我写了一个函数来处理一些ArrayList,并希望将列表传递给外部调用者。但我发现调用该函数后列表没有改变。
以下是一些测试代码(coz,它是一个演示,但说明了我的问题):
@Test
public void testList() {
List<Integer> l1 = new ArrayList<Integer>(5);
List<Integer> l2 = new ArrayList<Integer>(5);
l1.add(11); l1.add(12); l1.add(13); l1.add(14); l1.add(15);
l2.add(21); l2.add(22); l2.add(23); l2.add(24); l2.add(25);
System.out.println("outer l1: " + l1);
System.out.println("outer l2: " + l2);
subList(l1, l2); //call the function
System.out.println("after l1: " + l1);
System.out.println("after l2: " + l2);
}
protected static void subList(List<Integer> l1, List<Integer> l2) {
l1.remove(0); l1.remove(0);
l2 = l2.subList(0, 4);
System.out.println("inner l1: " + l1);
System.out.println("inner l2: " + l2);
}
结果是:
outer l1: [11, 12, 13, 14, 15]
outer l2: [21, 22, 23, 24, 25]
inner l1: [13, 14, 15] (in function, changed)
inner l2: [21, 22, 23, 24] (in function, changed too)
after l1: [13, 14, 15] (changed)
after l2: [21, 22, 23, 24, 25] (unchanged?!)
似乎List2没有被函数 subList(List l1,List l2)更改,而List1已更改。
ListV参数是否由CopyValue传递?那么,在函数中,当l2的引用发生变化时,JVM复制一个新的列表,原来的外部列表是否保持旧值?
如何编写“副作用”程序来修改ArrayList?
答案 0 :(得分:4)
引用总是通过Java中的值传递。因此,在被调用方法中为l2
分配新值不会更改调用方法中的引用。
您需要以下代码才能正常工作:
List<Integer> subList = new ArrayList<Integer>(l2.subList(0, 4));
l2.clear();
l2.addAll(subList);
答案 1 :(得分:1)
subList
方法创建一个新的列表对象,而旧的方法将保持不变。您可以在旧列表中调用clear
并使用addAll
将新列表中的数据复制回其中...
答案 2 :(得分:1)
问题出在这一行:
l2 = l2.subList(0, 4);
这会将l2
分配给一个新对象,由于Java只传递值(不是引用),因此只能修改场景中的原始对象。
答案 3 :(得分:1)
subList
是原始列表中数据的视图(请参阅documentation)。它与原始列表具有相同的引用,但任何结构更改(例如删除项目)都不会反映在原始列表中。
您应该对原始列表进行更改。
答案 4 :(得分:1)
l2.subList(0, 4);
它创建了一个新的list实例,你用l2保存,但在主类l2中创建的实例保持不变。
subList(List<Integer> l1, List<Integer> l2)
l2引用在主类中创建的实例,l2 = l2.subList(0, 4);
通过新创建的实例重写l2引用值。因此在主类中创建的实例保持不变。
答案 5 :(得分:0)
- subList
就像在原始列表中显示数据一样。
- 对sublist
所做的任何更改都不会在原始列表中反映。
- 最好使用Copy-Constructor
来执行此操作...
<强>例如强>
List<Integer> subList = new ArrayList<Integer>(l2.subList(0, 4));