0

ArrayList を処理する関数を作成し、リストを外部の呼び出し元に渡したいと考えています。しかし、関数を呼び出した後、リストが変更されていないことがわかりました。

ここにいくつかのテストコードがあります(これはデモですが、私の問題を示しています):

@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?!)

関数subList(List l1, List l2)によって List2 は変更されていないようですが、List1 は変更されています。

List パラメーターは CopyValue によって渡されますか?? では、関数内で l2 の参照が変更されると、JVM は新しいリストをコピーし、元の外側のリストは古い値を維持しますか?

ArrayList を変更する 「副作用」プロシージャを作成する方法は?

4

6 に答える 6

4

Java では、参照は常に値によって渡されます。したがって、呼び出されたメソッドに新しい値を割り当ててもl2、呼び出し元のメソッドの参照は変更されません。

動作させるには、次のコードが必要です。

List<Integer> subList = new ArrayList<Integer>(l2.subList(0, 4));
l2.clear();
l2.addAll(subList);
于 2012-09-18T12:07:05.450 に答える
1

このsubListメソッドは新しいリスト オブジェクトを作成しますが、古いリスト オブジェクトは変更されません。clear古いリストを呼び出してaddAll、新しいリストからデータをコピーして戻すことができます...

于 2012-09-18T12:03:46.520 に答える
1

問題は次の行にあります。

l2 = l2.subList(0, 4);

これは新しいオブジェクトに割り当てられl2ます。Java は値渡しのみ (参照ではない) であるため、シナリオでは元のオブジェクトのみを変更できます。

于 2012-09-18T12:04:42.800 に答える
1

subList、元のリスト内のデータのビューです (ドキュメントを参照してください)。元のリストと同じ参照がありますが、構造上の変更 (アイテムの削除など) は元のリストには反映されません。

元のリストに変更を加える必要があります。

于 2012-09-18T12:05:35.877 に答える
1

l2.subList(0, 4);リストの新しいインスタンスを作成し、これをl2で保持しますが、メインクラスl2で作成されたインスタンスは変更されません。

subList(List<Integer> l1, List<Integer> l2)l2はメインクラスで作成したインスタンスを参照し、l2 = l2.subList(0, 4);新しく作成したインスタンスでl2参照値を書き換えます。したがって、メインクラスで作成されたインスタンスは同じままです。

于 2012-09-18T12:07:45.033 に答える
0

- subList元のリストにあるデータのプレゼンテーションのようなものです。

-に加えられた変更は元のリストには反映されsublistません。

-これを行うには a を使用する方が良いCopy-Constructor...

例えば:

List<Integer> subList = new ArrayList<Integer>(l2.subList(0, 4));

于 2012-09-18T12:11:47.467 に答える