Insights into Company
← Java

Object

Understand the idea. Compare it. Explain it. Test yourself.

Question 11 of 12

What is deep copy?

Solution and explanation

What it is

A deep copy creates a new object and also recursively copies every mutable object it refers to, so the copy is fully independent of the original.

1. Copy constructors (preferred)

class Address {
    String city;
    Address(String city) { this.city = city; }
    Address(Address other) { this.city = other.city; }            // copy constructor
}

class Employee {
    String name;
    Address address;
    List<String> skills;

    Employee(Employee other) {
        this.name = other.name;                                   // String is immutable: sharing is safe
        this.address = new Address(other.address);                // new nested object
        this.skills = new ArrayList<>(other.skills);              // new list
    }
}

Employee e2 = new Employee(e1);
e2.address.city = "Noida";      // e1's address is unchanged

2. Deep clone()

@Override
protected Employee clone() throws CloneNotSupportedException {
    Employee copy = (Employee) super.clone();
    copy.address = new Address(this.address);
    copy.skills = new ArrayList<>(this.skills);
    return copy;
}

3. Serialization (simple but slow)

ObjectMapper mapper = new ObjectMapper();
Employee copy = mapper.readValue(mapper.writeValueAsString(e1), Employee.class);

Shallow vs deep

Shallow copyDeep copy
Top-level objectNewNew
Nested mutable objectsSharedCopied
Speed and memoryFast, little memorySlower, more memory
IndependenceChanges to nested objects affect bothFully independent

Note: immutable objects (String, records with immutable fields, List.of) never need copying. Making classes immutable is often simpler than deep copying.

Practice explaining this
Question 12 of 12

What is the difference between == and equals()?

Solution and explanation

Short answer

  • == compares references: are these the same object in memory? For primitives it compares values.
  • equals() compares logical content, as defined by the class. The default Object.equals() behaves like ==; classes such as String, Integer and List override it to compare content.
String a = new String("java");
String b = new String("java");
String c = a;

System.out.println(a == b);        // false — two different objects
System.out.println(a.equals(b));   // true  — same characters
System.out.println(a == c);        // true  — same object

String x = "java";
String y = "java";
System.out.println(x == y);        // true — both literals come from the String pool (don't rely on this)

Wrapper caching trap

Integer i1 = 127, i2 = 127;
System.out.println(i1 == i2);      // true  (cached -128..127)
Integer j1 = 128, j2 = 128;
System.out.println(j1 == j2);      // false (different objects)
System.out.println(j1.equals(j2)); // true

Overriding equals in your class

public class Employee {
    private final String empId;
    private final String name;

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Employee other)) return false;
        return empId.equals(other.empId);
    }

    @Override
    public int hashCode() { return Objects.hash(empId); }
}

The equals–hashCode contract

  • If a.equals(b) is true, a.hashCode() == b.hashCode() must also be true.
  • Override both together, or HashMap/HashSet will not find your objects.
  • equals must be reflexive, symmetric, transitive, consistent, and x.equals(null) must return false.

Rule: use == for primitives, enums and identity checks; use equals() (or Objects.equals(a, b) for null safety) for content.

Practice explaining this

Showing questions 11–12 of 12