Подтвердить что ты не робот

Изменение значения после его размещения в HashMap изменяет то, что внутри HashMap?

Если я создаю новый HashMap и новый List, а затем помещаю List внутри Hashmap с помощью произвольного ключа, а затем вызывается List.clear(), это повлияет на то, что я разместил внутри HashMap?

Более глубокий вопрос: когда я добавляю что-то в HashMap, новый объект копируется и помещается или является ссылкой на исходный объект?

Спасибо!

4b9b3361

Ответ 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 другому, то оба указывают на ту же ссылку в памяти.

    Карта hasmapB;

    hashmapB = hashmapA;

Если вы вносите изменения в любой из этих изменений, изменения будут отображаться как в HashMap, так и в том, что они ссылаются на одно и то же местоположение.

  1. Копировать по значению: Если вы хотите

clone/deepcopy/создать отдельную ячейку памяти/создать отдельный объект

hashmapB при копировании содержимого hashmapA

Map<Integer, Integer> hashmapB = new HashMap<>();;

hashmapB.putAll(hashmapA)

Примечание: ** Вы заметили разницу в обеих точках для объявления hashmapB? Во второй точке мы должны вызвать конструктор ** HashMap. Чтобы мы могли putAll данные hashmapA в hashmapB.

Ссылка

Ответ 8

Geeze people... все в Java проходит по значению. Когда вы передаете объект, значение, которое вы передаете, является ссылкой на объект. В частности, вы передаете копию ссылки на объект. В Java нет указателей, хотя ссылки похожи. Правильно!