Изменение значения после его размещения в HashMap изменяет то, что внутри HashMap?
Если я создаю новый HashMap и новый List, а затем помещаю List внутри Hashmap с помощью произвольного ключа, а затем вызывается List.clear()
, это повлияет на то, что я разместил внутри HashMap?
Более глубокий вопрос: когда я добавляю что-то в HashMap, новый объект копируется и помещается или является ссылкой на исходный объект?
Спасибо!
Ответы
Ответ 1
Что здесь происходит, так это то, что вы помещаете указатель на список в hashmap, а не на сам список.
Когда вы определяете
List<SomeType> list;
вы определяете указатель на список, а не сам список.
Когда вы делаете
map.put(somekey, list);
вы просто сохраняете копию указателя, а не список.
Если в другом месте вы следуете этому указателю и изменяете объект в конце, любой, кто держит этот указатель, все равно будет ссылаться на тот же измененный объект.
Подробнее о параметрах pass-by-value в Java см. http://javadude.com/articles/passbyvalue.htm.
Ответ 2
Java является передачей по ссылке.
Добавление списка в хэш-карту просто добавляет ссылку на хэш-карту, которая указывает на тот же список. Поэтому, очистка списка напрямую действительно очистит список, на который вы ссылаетесь в hashmap.
Ответ 3
Когда я добавляю что-то в HashMap, новый объект, скопированный и размещенный или ссылка на исходный объект помещается?
Это всегда ссылка на объект.
Если вы очистите HashMap, объект будет по-прежнему "жить".
Тогда объект будет уничтожен сборщиком мусора, если никто больше не ссылается на него.
Если вам нужно скопировать его, взгляните на метод Object.clone() и на интерфейс Cloneable
Ответ 4
Как правило, вы всегда имеете дело со ссылками на Java (если вы явно не создаете новый объект самостоятельно с "новым" [1]).
Следовательно, это ссылка, а не полная копия объекта, которую вы сохранили на карте, и изменение списка также повлияет на то, что вы видите при просмотре карты.
Это особенность, а не ошибка:)
[1] Puritans будет включать в себя "clone()" и сериализацию, но для большинства java-кода "новый" является способом получения объектов.
Ответ 5
Попробуйте
package test32;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
class Foo {
public Foo(int id, String name) {
this.id=id;
this.name=name;
}
public static void main(String[] args) {
HashMap strs = new HashMap();
// create a list of objects
List ls = new ArrayList();
ls.add(new Foo(1, "Stavros"));
ls.add(new Foo(2, "Makis"));
ls.add(new Foo(3, "Teo"));
ls.add(new Foo(4, "Jim"));
// copy references of objects from list to hashmap
strs.put("1", ls.get(0));
strs.put("2", ls.get(1));
strs.put("3", ls.get(2));
strs.put("4", ls.get(3));
System.out.println("list before change : " + ls);
System.out.println("map before change: " + strs);
// get an object from the hashmap
Foo f=strs.get("1");
// set a different value
f.setId(5);
// observe that the differences are reflected to the list and to the hashmap also
System.out.println("list after change : "+ls);
System.out.println("map after change: "+strs);
}
private int id;
public void setId(int id) {
this.id=id;
}
public int getId() {
return this.id;
}
private String name;
public void setName(String name) {
this.name=name;
}
public String getName() {
return this.name;
}
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(id);
sb.append("-");
sb.append(name);
return sb.toString();
}
}
Ответ 6
Правильный ответ для этого поясняется ниже:
Предположим, что у вас есть HashMap, называемый hashmap, и сначала вы помещаете пару значений ключа в этот HashMap, например. HashMap < "test1" , "test2" > .
После этого, когда вы передаете эту хэш-карту функции, в которой вы снова меняете свое значение на test3, например, hashmap.put( "test1" , "test3" ) и снова печатаете карту в основном методе, здесь возникает ошибка Java Pass by Value.
Причина:
Когда вы используете HashMap, он делает Хеширование для ключа (test1) и сохраняет значение. Когда вы передали его функции, в которой он снова изменил свое значение, он снова делает хэширование для одного и того же ключа и получает тот же адрес памяти и изменяет значение. Соответственно.
Вот почему, когда вы пытаетесь получить ключ "test1" , он дает результат как "test3"
Ответ 7
Map<Integer, Integer> hasmapA = new HashMap<>();
hasmapA.put("key1", "value1");
hasmapA.put("key2", "value2");
hasmapA.put("key3", "value3");
Если вы вносите изменения в любой из этих изменений, изменения будут отображаться как в HashMap, так и в том, что они ссылаются на одно и то же местоположение.
- Копировать по значению: Если вы хотите
clone/deepcopy/создать отдельную ячейку памяти/создать отдельный объект
hashmapB при копировании содержимого hashmapA
Map<Integer, Integer> hashmapB = new HashMap<>();;
hashmapB.putAll(hashmapA)
Примечание: **
Вы заметили разницу в обеих точках для объявления hashmapB? Во второй точке мы должны вызвать конструктор ** HashMap. Чтобы мы могли putAll данные hashmapA в hashmapB.
Ссылка
Ответ 8
Geeze people... все в Java проходит по значению. Когда вы передаете объект, значение, которое вы передаете, является ссылкой на объект. В частности, вы передаете копию ссылки на объект. В Java нет указателей, хотя ссылки похожи. Правильно!