I don't think I understand this topic even after doing some reading on it. I will try to describe as good as I can what I think happens in my code. If you can see the mistake, I would be grateful for any hints.
As far as I understand after clone() in the main method is called, the solution.clone() method is executed.
In there I create a new solution object (called cl), this is using the default constructor (creating a soultion object with a Map<String, User> users instance).
In code gmy's correct solution another Map<String, User> users is created, does anyone know why?
Then I loop through all the map entries of the original solution object , for every entry I take the name and the user object and add the name and a clone of the user object to my cl clone's map.
In the user clone method the default clone() is called, since only primitive types are being cloned.
My result is:
com.codegym.task.task21.task2107.Solution@d6c3b2cb
com.codegym.task.task21.task2107.Solution@324b1279
{Hubert=com.codegym.task.task21.task2107.Solution$User@279f2327, Zapp=com.codegym.task.task21.task2107.Solution$User@2ff4acd0}
{Hubert=com.codegym.task.task21.task2107.Solution$User@54bedef2, Zapp=com.codegym.task.task21.task2107.Solution$User@5caf905d}
To me this looks like it actually worked, the solution as well as the users got cloned and don't share the same reference, but the validation fails. Any ideas?
package com.codegym.task.task21.task2107;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;
/*
Deep cloning of a map
*/
public class Solution implements Cloneable{
public static void main(String[] args) {
Solution solution = new Solution();
solution.users.put("Hubert", new User(172, "Hubert"));
solution.users.put("Zapp", new User(41, "Zapp"));
Solution clone = null;
try {
clone = (Solution) solution.clone();
System.out.println(solution);
System.out.println(clone);
System.out.println(solution.users);
System.out.println(clone.users);
} catch (CloneNotSupportedException e) {
e.printStackTrace(System.err);
}
}
@Override
protected Object clone() throws CloneNotSupportedException {
Solution cl = new Solution();
for(Map.Entry<String, User> m : this.users.entrySet()){
String name =m.getKey();
User u = m.getValue();
cl.users.put(name, (User)u.clone());
}
return cl;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Solution solution = (Solution) o;
return Objects.equals(users, solution.users);
}
@Override
public int hashCode() {
return Objects.hash(users);
}
protected Map<String, User> users = new LinkedHashMap();
public static class User implements Cloneable {
int age;
String name;
public User(int age, String name) {
this.age = age;
this.name = name;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
}