2012-04-09 4 views
67

Я пытаюсь сохранить временный контейнер класса, который содержит элемент:Копирование HashMap в Java

HashMap<Integer,myObject> myobjectHashMap 

класс называется myobjectsList

Тогда я

myojbectsListA = new myojbectsList(); 
myojbectsListB = new myobjectsList(); 

тогда: Добавить некоторые элементы хэш-функции в A (like2)

затем

myobjectListB = myobjectListA; //B has 2 

then: Добавить элементы hashmap в A; (например, еще 4)

затем верните A в предметы, хранящиеся в B;

myobjectListA = myobjectListb; 

, но когда я делаю это B растет с A, а я добавляю элементы HashMap А. А теперь имеет 6 пунктов в нем, потому что B был 6.

Я хочу, чтобы иметь оригинал 2 еще в конце после последнего подсчета в C++ я бы использовал копию с объектами, что такое эквивалент java?

Добавлено: OK Я ничего не объяснил, объясняя это. MyObjectsList не содержит HashMap, он получен из класса MyBaseOjbectsList, у которого есть член HashMap, а MyObjectsList расширяет MyBaseOjbectsList. Это имеет значение.?

+1

Вы можете оставить [SSCCE] (http://sscce.org), чтобы дать лучшее понимание того, что вы сделали до сих пор? – assylias

+2

Ваши объекты должны реализовывать интерфейс Cloneable, в противном случае назначения, такие как MyObjectB = MyObjectA, просто указывают JVM, что обе переменные указывают на одно и то же местоположение в памяти. Не два разных объекта. –

+0

Btw, подавляющая идиома (практически закон) заключается в том, чтобы капитализировать имена классов. Это сделает ваши примеры более читабельными для тех из нас, кто использует эти вещи в качестве быстрых сигналов во время сканирования примера кода. –

ответ

2

В Java, когда вы пишете:

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

objectA и objectB одинаковы и указывают на то же ссылки. Изменение одного изменит другое. Поэтому, если вы измените состояние objectA (не его ссылка) objectB также отразит это изменение.

Однако, если вы пишете:

objectA = new Object() 

Тогда objectB все еще указывает на первый объект, созданный (оригинал objectA), а objectA теперь указывает на новый объект.

+0

, что объясняет проблему, какое решение? Или это ограничение Java без работы? – user691305

+1

Это не ограничение, так оно и работает. Если вам нужны два разных объекта, вы создаете 2 объекта - если вы создаете только один объект, то все переменные, указывающие на этот объект, равны. – assylias

+0

Предлагаю вам создать новый вопрос со всем соответствующим кодом (в идеале [SSCCE] (http://sscce.org)) и объяснить, что именно вы пытаетесь достичь. – assylias

8

Разница заключается в том, что в C++ ваш объект находится в стеке, тогда как в Java ваш объект находится в куче. Если A и B являются объекты, в любое время и в Java вы

B = A

А и точку В тот же объект. Поэтому все, что вы делаете, чтобы А вы к B и наоборот

использовать новый HashMap(), если вы хотите два разных объекта

И вы можете использовать Map.putAll (...) для копирования данных между двумя картами

+0

Это то же самое, что сказать, что Java все по ссылке, а C++ иногда ссылается и иногда стоит? Но я не хочу HashMap, я не дублирую копию класса, который я могу использовать в качестве временного хранилища. – user691305

+0

У меня нет доступа к HashMap в базовом классе. Опять же, я должен работать с классами, полученными из базы. Я не могу получить доступ к HashMap. – user691305

0

Что вы назначаете одному объекту другому, все, что вы делаете, копирует ссылку на объект, а не его содержимое. Вам нужно сделать свой объект B и вручную скопировать содержимое объекта A в него.

Если вы делаете это часто, вы можете рассмотреть возможность применения метода clone() для класса, который будет создавать новый объект того же типа, и скопировать все его содержимое в новый объект.

+0

Клон сделал то же самое, что, казалось, передал ссылку. – user691305

+0

Кроме того, когда вы увеличиваете счет HashMap, копия тоже не хочет этого. Я хочу контейнеры idependent (в этом случае классы) того же типа. – user691305

156

Если вам нужна копия HashMap, вам нужно построить новую.

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

Это создаст (неглубокую) копию карты.

+2

или если он уже создан, используйте 'myObjectListB.addAll (myObjectListA)' –

+0

Возможно, я не понимаю этого, но мне не нужна копия карты. Мне нужна копия класса, содержащего карту. ? Там для myObjectListB должен быть класс, полученный из MyojbectsList, а не hashmap. – user691305

+0

Также я не понимаю реализацию «addAll (myOjbejctListA)» – user691305

11

Вы также можете использовать

clone() 

метод, чтобы скопировать все элементы из одного HashMap другого HashMap

Программы для копирования всех элементов из одного HashMap к другому источнику

import java.util.HashMap; 

public class CloneHashMap {  
    public static void main(String a[]) {  
     HashMap hashMap = new HashMap();  
     HashMap hashMap1 = new HashMap();  
     hashMap.put(1, "One"); 
     hashMap.put(2, "Two"); 
     hashMap.put(3, "Three"); 
     System.out.println("Original HashMap : " + hashMap); 
     hashMap1 = (HashMap) hashMap.clone(); 
     System.out.println("Copied HashMap : " + hashMap1);  
    }  
} 

: http://www.tutorialdata.com/examples/java/collection-framework/hashmap/copy-all-elements-from-one-hashmap-to-another

+10

Вы можете, но вы _probably_ не должны, потому что Cloneable по существу сломан, за Эффективный Java # 11 Джошуа Блоха. –

+8

также обратите внимание, что clone() возвращает неглубокую копию. –

+2

Что означает мелкое значение? Если он не скопирует карту точно (с неповрежденными ключами/значениями), зачем беспокоиться? Можно также создать новую карту, не так ли? – Azurespot

2

Поскольку этот вопрос по-прежнему отсутствует и у меня была аналогичная проблема, я постараюсь ответить на это. Проблема (как уже упоминалось ранее) заключается в том, что вы просто копируете ссылки на один и тот же объект, и, таким образом, модификация на копии также изменит исходный объект. Итак, вам нужно скопировать объект (ваше значение карты). Самый простой способ сделать это - сделать все ваши объекты реализацией сериализуемого интерфейса. Затем выполните сериализацию и десериализацию карты, чтобы получить реальную копию. Вы можете сделать это самостоятельно или использовать apache commons SerializationUtils # clone(), который вы можете найти здесь: https://commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/apache/commons/lang/SerializationUtils.html Но имейте в виду, что это самый простой подход, но дорого стоит задача сериализации и десериализации множества объектов.

4

Здесь небольшое (ОГРОМНОЕ) преуменьшение. Потому что, если вы хотите скопировать HashMap, который более структурирован HashMap.putAll() справится со значением, поскольку он не знает, как точно скопировать объект. Например

private HashMap <Integer, HashMap<Integer,List<Float>>> DataA = new HashMap<>(); 
private HashMap <Integer, HashMap<Integer,List<Float>>> DataB = new HashMap<>(); 

    DataA.put(1,new HashMap<>()); 
    DataB.putAll(DataA); 

    DataA.put(2,new HashMap<>()); 
    if(DataB.size() == 2){ // true 
     Log.i("","Sory object was copied - not the value"); 
    } 

Так basicaly вам нужно будет скопировать все сами, как здесь

List <Float> aX = new ArrayList<>(someList); 
List <Float> aY = new ArrayList<>(somteList1); 

List <Float> gX = new ArrayList<>(someList2); 
List <Float> gY = new ArrayList<>(someList3); 


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

HashMap<Integer,List<Float>> Map1 = new HashMap<>(); 
Map1.put(X_axis,gX); 
Map1.put(Y_axis,gY); 
Data.put(Sensor.TYPE_GYROSCOPE,Map1); 
Смежные вопросы