Ребят подскажите такой момент:
@Override
public Object clone() throws CloneNotSupportedException {
try {
AmigoSet<E> amigoSet = new AmigoSet<E>();
amigoSet.map = new HashMap<>(this.map);
return amigoSet;
} catch (Throwable e) {
throw new InternalError();
}
}
К примеру, я клонирую данные из переменной map своего оригинального объекта(который является коллекцией , назовем ее origAmigo) ,в переменную map нового объекта amigoSet (как указано в коде)
Выполняя данную операцию, я ожидаю, что у моего нового объекта amigoSet, переменная map примет те же значения, что и у переменной map оригинала(origAmigo)
И это действительно происходит, но, помимо клонирования значений map, у меня клонируются еще и объекты, содержащиеся в самом объекте origAmigo.
Почему помимо map, у меня клонируются еще и значение коллекции origAmigo?
надеюсь ясно сформулировал
Tural
36 уровень
конструктор классов коллекции
Решен
Комментарии (6)
- популярные
- новые
- старые
Для того, чтобы оставить комментарий Вы должны авторизоваться
KIRAРазработчик в prosv.ruExpert
23 марта 2022, 09:52
я клонирую данные из переменной map
Данные из map вы не клонируете, вы клонируете map.
у меня клонируются еще и объекты, содержащиеся в самом объекте origAmigo.
Тут не ясно о чем вы говорите, у вас кроме заглушки и map ничего нет
0
Tural
23 марта 2022, 11:55
смотрите,
public class AmigoSet<E> extends AbstractSet<E> implements Serializable, Cloneable, Set<E> {
private static final Object PRESENT = new Object();
private transient HashMap<E, Object> map;
public AmigoSet() {
this.map = new HashMap<>();
}
public AmigoSet(Collection<? extends E> collection) {
this.map = new HashMap<>(Math.max((int) (collection.size() / .75f) + 1, 16));
addAll(collection);
}
@Override
public boolean add(E e) {
return map.put(e, PRESENT) == null;
}
public static void main(String[] args) {
AmigoSet<Integer> amigoSet = new AmigoSet<Integer>();
Collections.addAll(amigoSet, 12, 6, 4, 8, 235, 8, 4, 2);
исходя из метода add, понимаем, что все эти значения будут также занесены в map
Теперь создадим новый объект
AmigoSet<?> newAmigoSet = (AmigoSet<?>) amigoSet.clone();
Для этого вызываю метод clone
На выходе, получается, что мой новый объект (newAmigoSet) содержит в себе все данные map объекта (amigoSet что очевидно),
а также, содержит в себе объекты, которые находились внутри amigoSet (12,6,4,8,235,8,4.2)
не понимаю как именно скопировались значения 12,6,4,8,235,8,4.2 в новый объект
}
@Override
public Object clone() throws CloneNotSupportedException {
try {
AmigoSet<E> amigoSet = new AmigoSet<E>();
amigoSet.map = new HashMap<>(this.map);
return amigoSet;
} catch (Throwable e) {
throw new InternalError();
}
}
0
KIRAРазработчик в prosv.ruExpert
23 марта 2022, 11:59
Вы когда новую HashMap создаете в конструктор к ней передаете старую
amigoSet.map = new HashMap<>(this.map);
Добавляете все Entry из старой в новую
0
Tural
23 марта 2022, 12:14
это да, и очевидно что новый. map содержит все значения старой map
если я напишу
System.out.println(amigoSet);
вывод:
[2, 4, 6, 8, 235, 12]
я получаю значения не из map, а из моей коллекции amigoSet
после клонирования мой новый объект тоже содержит в себе эти же данные
System.out.println(newaAmigoSet);
вывод:
[2, 4, 6, 8, 235, 12]
не понимаю как они туда попадают.
про клонирование map все понятно
0
KIRAРазработчик в prosv.ruExpert
23 марта 2022, 12:39решение
Давайте по порядку, сам ваш сет ничего не хранит кроме
Что происходит когда вы что то добавляете в амигоСет, вы просто добавляете ключи в map внутри амигоСета + заглушка
У амигоСета есть метод который возвращает интератор сета ключей у map
Когда вы выводите System.out.println(amigoSet); вы итератором обходите и выводите все ключи map. Сам амигоСет не хранит ключи - значения
+2
Tural
23 марта 2022, 12:53
всеее, Спасибо огромное, разобрался)
0