135

member を含むクラスの一時的なコンテナを保持しようとしています:

HashMap<Integer,myObject> myobjectHashMap

myobjectsList というクラス

それから私はします

myobjectsListA = new myobjectsList();
myobjectsListB = new myobjectsList();

次に: いくつかのハッシュマップ項目を A に追加します (2 のように)

それから:

myobjectListB = myobjectListA; //B has 2

次に: ハッシュマップ項目を A に追加します (さらに 4 つなど)

次に: A を B に格納されているアイテムに戻します。

myobjectListA = myobjectListb;

しかし、これを行うと、ハッシュマップ項目を A に追加している間に、B が A と共に成長します。B には 6 つの項目があったため、A には 6 つの項目が含まれています。

最後の割り当ての後、Aには元の2が最後に残っている必要があります。C++ ではオブジェクトでコピーを使用しますが、Java に相当するものは何ですか?

追加: OK、これについての説明を省略しました。MyObjectsListHashMap を含まずMyBaseOjbectsList、HashMap メンバーとMyObjectsListextendsを持つクラスから派生しますMyBaseOjbectsList。これは違いがありますか?

4

11 に答える 11

256

HashMap のコピーが必要な場合は、新しいものを作成する必要があります。

myobjectListB = new HashMap<Integer,myObject>(myobjectListA);

これにより、マップの (浅い) コピーが作成されます。

于 2012-04-09T20:31:42.587 に答える
13

違いは、C++ ではオブジェクトがスタック上にあるのに対し、Java ではオブジェクトがヒープ内にあることです。A と B がオブジェクトの場合、Java ではいつでも次のようにします。

B = A

A と B は同じオブジェクトを指しているため、A に対して行うことはすべて B に対して行うことになり、その逆も同様です。

HashMap()2 つの異なるオブジェクトが必要な場合は、new を使用します。

Map.putAll(...)また、2 つのマップ間でデータをコピーするために使用できます。

于 2012-04-09T20:25:05.420 に答える
6

ここには小さな (巨大な) 控えめな表現があります。HashMapネストされた構造を持つをコピーする場合HashMap.putAll()は、オブジェクトを正確にコピーする方法がわからないため、参照によってコピーされます。例えば:

import java.util.*;
class Playground {
    public static void main(String[ ] args) {
        Map<Integer, Map<Integer,List<Float>>> dataA = new HashMap<>();
        Map<Integer, Map<Integer,List<Float>>> dataB = new HashMap<>();

        dataA.put(1, new HashMap<>());
        dataB.putAll(dataA);

        assert(dataB.get(1).size() == 0);

        dataA.get(1).put(2, new ArrayList<>());

        if (dataB.get(1).size() == 1) { // true
            System.out.println(
                "Sorry object reference was copied - not the values");
        }
    }
}

したがって、基本的には、ここのように自分でフィールドをコピーする必要があります

List <Float> aX = new ArrayList<>(accelerometerReadingsX);
List <Float> aY = new ArrayList<>(accelerometerReadingsY);

List <Float> gX = new ArrayList<>(gyroscopeReadingsX);
List <Float> gY = new ArrayList<>(gyroscopeReadingsY);

Map<Integer, Map<Integer, Float>> readings = new HashMap<>();

Map<Integer,List<Float>> accelerometerReadings = new HashMap<>();
accelerometerReadings.put(X_axis, aX);
accelerometerReadings.put(Y_axis, aY);
readings.put(Sensor.TYPE_ACCELEROMETER, accelerometerReadings);

Map<Integer,List<Float>> gyroscopeReadings = new HashMap<>();
gyroscopeReadings.put(X_axis, gX);
gyroscopeReadings.put(Y_axis, gY);
readings.put(Sensor.TYPE_GYROSCOPE, gyroscopeReadings);
于 2016-02-08T09:24:26.563 に答える
4

Java では、次のように記述します。

Object objectA = new Object();
Object objectB = objectA;

objectAobjectBは同じで、同じ参照を指しています。一方を変えると他方も変わる。objectAしたがって、 (その参照ではなく)の状態を変更すると、objectBその変更も反映されます。

ただし、次のように書くと:

objectA = new Object()

ThenobjectBはまだ作成した最初のオブジェクト (元のobjectA) をobjectA指していますが、現在は新しいオブジェクトを指しています。

于 2012-04-09T20:24:27.943 に答える
0

あるオブジェクトを別のオブジェクトに割り当てると、オブジェクトの内容ではなく、オブジェクトへの参照をコピーするだけです。オブジェクトBを取得し、オブジェクトAの内容を手動でコピーする必要があります。

これを頻繁に行う場合clone()は、同じタイプの新しいオブジェクトを作成するメソッドをクラスに実装し、そのすべてのコンテンツを新しいオブジェクトにコピーすることを検討してください。

于 2012-04-09T20:30:07.990 に答える
0

OPは、HashMapが存在する基本クラスにアクセスできないと述べているため、使用できるオプションはほとんどないのではないかと思います。

Java でオブジェクトのディープ コピーを実行する (非常に遅く、リソースを大量に消費する) 方法の 1 つは、多くのクラスが意図的に (または意図せずに) 拡張する「Serializable」インターフェイスを悪用し、これを利用してクラスを ByteStream にシリアル化することです。逆シリアル化すると、問題のオブジェクトのディープ コピーが作成されます。

このガイドはこちらにあります: https://www.avajava.com/tutorials/lessons/how-do-i-perform-a-deep-clone-using-serializable.html

于 2019-03-04T16:39:57.290 に答える