3

いくつかの異なる ArrayLists に追加したオブジェクトがあります。すべてのリストを変更するのは避けたいので、すべてのリストが変更されるようにポインタを変更しようとしています。しかし、オブジェクトを null に設定したい場合、それを機能させることはできません。例えば:

ArrayList<Point> list1 = new ArrayList<Point>();
ArrayList<Point> list2 = new ArrayList<Point>();
Point a = new Point(2, 3);
list1.add(a); list2.add(a);

この時点で、両方のリストに同じオブジェクトを指す項目があります。値は「2、3」です。オブジェクトの値を変更した場合。次に、両方のリストが変更されます。

a.set(5,5);

これで、両方のリストに値「5, 5」のアイテムが含まれます。しかし、値をnullに設定しようとすると。

a = null;

現在はanull に設定されていますが、オブジェクトの両方のリストはまだ "5, 5" であり、私が望んでいたように null ではありません。クラスにメソッドを追加して、Pointそれ自体をnullに設定しようとさえしました。しかし、私もそれを機能させることができませんでした。ポインターだけを変更して、すべてのリストのオブジェクトを削除するにはどうすればよいですか?

4

5 に答える 5

5

参照変数が保持するオブジェクトの状態を変更することができ、これは同じオブジェクトを参照するすべての変数に反映されますが、参照変数の割り当てを変更すると、その変数のみに影響します。参照されているオブジェクトは変更されていません -- 当然のことです。

于 2012-04-06T02:39:43.733 に答える
2

Java では、「ポインタ」(より正確には「参照」) からオブジェクトを削除することはできません。オブジェクトが逆参照された (つまり、それを指している参照がない) 場合、そのオブジェクトはガベージ コレクションの候補になります。Java のガベージ コレクターは自動的にオブジェクトの削除をfree()処理します。手動でメモリを管理する必要がある他の言語 (C/C++ が思い浮かびます) のような操作はありません。

あなたの質問について: のremove()メソッドを使用して両方のリストからオブジェクトを削除するか、インデックス ( ) を指定してリスト内ArrayListのオブジェクトを手動で設定することはできますが、外部参照 (リスト)に。nulllist.set(index, null)null

于 2012-04-06T02:49:15.153 に答える
1

短い答えは「いいえ」です。オブジェクトへのポインターを変更しても、オブジェクトの内容を変更することはできません。

a = null; オブジェクトではなく、ポインターをクリアするだけです。

于 2012-04-06T02:38:41.133 に答える
1

ポインターだけを変更して、すべてのリストのオブジェクトを削除するにはどうすればよいですか?

何もない。そんなことはありえない。リスト内のオブジェクトへの参照を無効にする (またはリストから削除する) 場合は、各リストに対して操作を実行する必要があります。

リストを変更できない場合は、次の代替案を検討してください。

  1. Pointポイントが「有効」であるかどうかを示す追加のフィールドを持つ別のクラスを使用し、リストを調べているコードにこのフィールドをチェックさせます。

  2. Point への null 許容参照を表すカスタム クラスを作成します。例えば

      public class PointRef {
          private Point p;
          public PointRef(Point p) { this.p = p; }
          public Point get() { return p; }
          public void invalidate() { p = null; }
      }
    
      ArrayList<PointRef> list1 = new ArrayList<PointRef>();
      ArrayList<PointRef> list2 = new ArrayList<PointRef>();
      PointRef a = new PointRef(new Point(2, 3));
      list1.add(a); list2.add(a);
    
      ...
    
      a.invalidate;
      // Now both lists contain hold a PointRef that points to a null Point.
    

しかし、これらは両方とも、リストとそれに含まれる Point オブジェクトの使用をより複雑にします。

(@Jeffrey の回答では、WeakReferenceクラスの使用が提案されていますが、セマンティクスが間違っています。特に、GC がオブジェクトへの強い参照がないことを検出すると、参照は「壊れます」。それはユースケースで必要とされるものではありません...私があなたの質問を正しく理解していれば.)


ちなみに、あなたがしようとしていることを、あなたが提案する方法で実行できるプログラミング言語は思いつきません。

于 2012-04-06T03:42:55.237 に答える
1

他の人が述べたように、あなたが求めていることを行う簡単な方法はありません。あなたができることは、私はこれをお勧めしませんがWeakReference、あなたListの s で s を使用することです。Point弱参照は、ガベージ コレクションを妨げません。

List<WeakReference<Point>> list = new ArrayList<>();
Point p = new Point();
list.add(new WeakReference<>(p));
System.out.println(p);
System.out.println(list.get(0).get());

p = null;

System.gc(); System.gc(); System.gc(); System.gc(); // hopefully the GC collects p by now

System.out.println(list.get(0).get()); // null!

両方から手動で実行removeする方がはるかに簡単です。PointList

于 2012-04-06T03:22:00.820 に答える