[{"data":1,"prerenderedAt":115},["ShallowReactive",2],{"qa-\u002Fjava\u002Foop\u002Fequals-hashcode":3},{"page":4,"siblings":95,"blog":112},{"id":5,"title":6,"body":7,"description":11,"difficulty":14,"extension":15,"framework":16,"frameworkSlug":17,"meta":18,"navigation":19,"order":20,"path":21,"questions":22,"questionsCount":85,"related":86,"seo":87,"seoDescription":88,"stem":89,"subtopic":90,"topic":91,"topicSlug":92,"updated":93,"__hash__":94},"qa\u002Fjava\u002Foop\u002Fequals-hashcode.md","Equals Hashcode",{"type":8,"value":9,"toc":10},"minimark",[],{"title":11,"searchDepth":12,"depth":12,"links":13},"",2,[],"hard","md","Java","java",{},true,5,"\u002Fjava\u002Foop\u002Fequals-hashcode",[23,28,33,37,41,45,49,53,57,61,65,69,73,77,81],{"id":24,"difficulty":25,"q":26,"a":27},"equals-vs-==","easy","What is the difference between == and equals()?","- **`==`** compares **references** for primitives' values and for objects'\n  *identity* — are these the **same object** in memory?\n- **`equals()`** compares **logical value**, as defined by the class. The\n  `Object` default is just `==`, so it means nothing useful until overridden.\n\n```java\nString a = new String(\"x\"), b = new String(\"x\");\na == b;            \u002F\u002F false — two different objects\na.equals(b);       \u002F\u002F true  — same characters\n```\n\n`==` on objects almost always indicates a bug when you meant value equality\n(the classic `String` comparison mistake). **Rule of thumb:** `==` for\nprimitives and identity; `equals()` for value.\n",{"id":29,"difficulty":30,"q":31,"a":32},"object-equality-identity","medium","What is the difference between identity, equality and equivalence?","- **Identity** — `a == b`: are they the *same object* in memory?\n- **Equality** — `a.equals(b)`: are they *logically the same value*, per the\n  class's definition?\n- Some classes also expose **ordering equivalence** via `compareTo == 0`.\n\n```java\nString a = new String(\"x\"), b = new String(\"x\");\na == b;            \u002F\u002F false (identity)\na.equals(b);       \u002F\u002F true  (equality)\n\nBigDecimal x = new BigDecimal(\"1.0\"), y = new BigDecimal(\"1.00\");\nx.equals(y);       \u002F\u002F false! (scale differs)\nx.compareTo(y) == 0; \u002F\u002F true  (numeric equivalence)\n```\n\n`BigDecimal` is the classic gotcha where `equals` and `compareTo` disagree.\n",{"id":34,"difficulty":25,"q":35,"a":36},"default-equals","What does the default Object.equals() do?","The `Object` implementation compares **reference identity** — it returns `true`\nonly if both references point to the **exact same object** (`this == other`).\nSo unless you override it, two distinct objects with identical state are \"not\nequal.\"\n\n```java\nclass Point { int x, y; }\nPoint a = new Point(), b = new Point();   \u002F\u002F both (0,0)\na.equals(b);   \u002F\u002F false — default equals is identity\n```\n\nThat's why value classes (`String`, `Integer`, `LocalDate`) override `equals`.\n**Rule of thumb:** if \"two of these with the same contents should be equal,\" you\nmust override `equals` (and `hashCode`).\n",{"id":38,"difficulty":14,"q":39,"a":40},"equals-hashcode","What is the equals\u002FhashCode contract?","If you override `equals`, you **must** override `hashCode`, obeying:\n\n1. Equal objects (`a.equals(b)`) **must** have equal hash codes.\n2. `equals` must be reflexive, symmetric, transitive, and consistent.\n3. Unequal objects *may* share a hash code (collisions are allowed).\n\n```java\nclass Point {\n  final int x, y;\n  @Override public boolean equals(Object o) {\n    if (this == o) return true;\n    if (!(o instanceof Point p)) return false;\n    return x == p.x && y == p.y;\n  }\n  @Override public int hashCode() { return Objects.hash(x, y); }\n}\n```\n\nBreak the contract and **hash-based collections silently misbehave**: a\n`HashMap`\u002F`HashSet` may fail to find an object whose `hashCode` doesn't match\nits `equals`. Use `Objects.hash(...)` \u002F `Objects.equals(...)` to implement them.\n",{"id":42,"difficulty":14,"q":43,"a":44},"why-override-both","Why must you override hashCode whenever you override equals?","Because hash-based collections (`HashMap`, `HashSet`) **find a bucket by\n`hashCode` first**, then check `equals` within it. If two `equals` objects have\n**different** hash codes, they land in different buckets and the collection\nnever finds the match.\n\n```java\nclass Key {\n  final int id;\n  @Override public boolean equals(Object o) { \u002F* by id *\u002F return o instanceof Key k && k.id == id; }\n  \u002F\u002F no hashCode override -> uses identity hash!\n}\nvar set = new HashSet\u003CKey>();\nset.add(new Key(1));\nset.contains(new Key(1));   \u002F\u002F false! equal but different hashCode\n```\n\n**Rule of thumb:** equals and hashCode are a package deal — override neither or\nboth, derived from the **same fields**.\n",{"id":46,"difficulty":14,"q":47,"a":48},"equals-properties","What properties must a correct equals() satisfy?","The `equals` contract requires five properties:\n\n- **Reflexive** — `x.equals(x)` is true.\n- **Symmetric** — `x.equals(y)` iff `y.equals(x)`.\n- **Transitive** — if `x=y` and `y=z`, then `x=z`.\n- **Consistent** — repeated calls give the same result (no random\u002Ftime inputs).\n- **Non-null** — `x.equals(null)` is false (never throws).\n\n```java\n@Override public boolean equals(Object o) {\n  if (this == o) return true;            \u002F\u002F reflexive fast-path\n  if (!(o instanceof Point p)) return false; \u002F\u002F handles null + wrong type\n  return x == p.x && y == p.y;           \u002F\u002F symmetric & transitive by construction\n}\n```\n\nSymmetry\u002Ftransitivity are the ones that break with inheritance. **Rule of\nthumb:** compare the same fields both ways and reject null\u002Fother types up front.\n",{"id":50,"difficulty":14,"q":51,"a":52},"getclass-vs-instanceof","Should equals() use instanceof or getClass()?","It's a trade-off:\n\n- **`instanceof`** allows a subclass to be `equals` to its parent, but can break\n  **symmetry** if a subclass adds state.\n- **`getClass()`** requires exact same class — preserves symmetry\u002Ftransitivity\n  but means no subclass instance is ever equal to a parent instance (breaks\n  Liskov for equality).\n\n```java\n\u002F\u002F instanceof — flexible, but Sub vs Base symmetry is fragile\nif (!(o instanceof Point p)) return false;\n\u002F\u002F getClass — strict, symmetric\nif (o == null || getClass() != o.getClass()) return false;\n```\n\nEffective Java recommends `instanceof` **plus making value classes `final`** (or\nusing composition) to sidestep the subclass problem. **Rule of thumb:** prefer\n`instanceof` on a `final`\u002Frecord value type.\n",{"id":54,"difficulty":30,"q":55,"a":56},"objects-helpers","How do java.util.Objects helpers simplify equals and hashCode?","`Objects` provides null-safe utilities so you don't hand-roll boilerplate:\n\n- `Objects.equals(a, b)` — null-safe equality (no NPE if `a` is null).\n- `Objects.hash(f1, f2, ...)` — combines fields into one hash code.\n- `Objects.requireNonNull(x)` — guard constructor args.\n\n```java\n@Override public boolean equals(Object o) {\n  if (this == o) return true;\n  if (!(o instanceof User u)) return false;\n  return age == u.age && Objects.equals(name, u.name); \u002F\u002F null-safe\n}\n@Override public int hashCode() { return Objects.hash(name, age); }\n```\n\n**Rule of thumb:** use `Objects.equals`\u002F`Objects.hash` for the fields — concise,\nnull-safe, and consistent with each other.\n",{"id":58,"difficulty":14,"q":59,"a":60},"mutable-key","Why is it dangerous to use a mutable object as a HashMap key?","A `HashMap` places an entry in a bucket based on the key's `hashCode` **at\ninsertion time**. If you then **mutate** a field that `hashCode`\u002F`equals` depend\non, the key's hash changes — it now hashes to a *different* bucket, and lookups\ncan no longer find it.\n\n```java\nvar map = new HashMap\u003CList\u003CInteger>, String>();\nvar key = new ArrayList\u003C>(List.of(1));\nmap.put(key, \"v\");\nkey.add(2);                 \u002F\u002F mutated — hashCode changed\nmap.get(key);               \u002F\u002F null! stranded in the old bucket\n```\n\n**Rule of thumb:** use **immutable** keys (`String`, `Integer`, records,\nenums). If a key must be mutable, never change the fields used by\n`equals`\u002F`hashCode` while it's in the map.\n",{"id":62,"difficulty":14,"q":63,"a":64},"compareto-consistency","Should compareTo be consistent with equals?","It **should** be (`x.compareTo(y) == 0` iff `x.equals(y)`), and sorted\ncollections assume it. When they disagree, `TreeSet`\u002F`TreeMap` — which use\n`compareTo`, **not** `equals` — behave surprisingly.\n\n```java\nvar set = new TreeSet\u003CBigDecimal>();\nset.add(new BigDecimal(\"1.0\"));\nset.add(new BigDecimal(\"1.00\"));   \u002F\u002F compareTo == 0 -> treated as duplicate!\nset.size();                         \u002F\u002F 1, even though equals() says they differ\n```\n\n`BigDecimal` deliberately violates this (scale matters to `equals` but not\n`compareTo`). **Rule of thumb:** keep `compareTo` consistent with `equals`\nunless you have a documented reason — and know `TreeSet`\u002F`TreeMap` use ordering,\nnot equality.\n",{"id":66,"difficulty":25,"q":67,"a":68},"string-equals","Why should you compare strings with equals() and not ==?","`==` compares **references**. String literals are **interned** (shared from a\npool), so `==` sometimes appears to work — but any `String` built at runtime\n(`new`, concatenation, input) is a different object, and `==` then returns\n`false` for equal text.\n\n```java\nString a = \"hi\", b = \"hi\";\na == b;              \u002F\u002F true — both the interned literal\nString c = new String(\"hi\");\na == c;              \u002F\u002F false — different object\na.equals(c);         \u002F\u002F true — same characters\n```\n\n**Rule of thumb:** always use `.equals()` (or `Objects.equals`) for string\ncontent; `==` for strings is a latent bug that \"works\" until the data comes\nfrom outside.\n",{"id":70,"difficulty":25,"q":71,"a":72},"tostring","Why and how do you override toString?","The default `toString` returns `ClassName@hexHashCode` — useless in logs. Override\nit to return a readable representation, which is automatically used in string\nconcatenation, `println`, and debuggers.\n\n```java\nclass User {\n  String name; int age;\n  @Override public String toString() {\n    return \"User{name=\" + name + \", age=\" + age + \"}\";\n  }\n}\nSystem.out.println(new User()); \u002F\u002F User{name=null, age=0}\n```\n\nIt's purely for human-readable diagnostics — don't parse it programmatically.\nIDEs and `record`s can generate it for you.\n",{"id":74,"difficulty":30,"q":75,"a":76},"record-equals","How do records implement equals, hashCode and toString?","A `record` **auto-generates** `equals`, `hashCode`, and `toString` from its\ncomponents — value-based equality with no boilerplate and no risk of forgetting\n`hashCode`. Two records are equal iff all their components are equal.\n\n```java\nrecord Point(int x, int y) { }\nnew Point(1, 2).equals(new Point(1, 2));   \u002F\u002F true — generated equals\nnew Point(1, 2).hashCode() == new Point(1, 2).hashCode(); \u002F\u002F true\nnew Point(1, 2).toString();                 \u002F\u002F \"Point[x=1, y=2]\"\n```\n\nYou *can* override them, but rarely should. **Rule of thumb:** for an immutable\nvalue type, a `record` is the safest way to get a correct equals\u002FhashCode —\nreach for it before hand-writing them.\n",{"id":78,"difficulty":30,"q":79,"a":80},"hashcode-distribution","What makes a good hashCode implementation?","A good `hashCode`:\n\n- Is **consistent** with `equals` (equal objects -> equal hashes).\n- **Distributes** values across the `int` range so buckets fill evenly (few\n  collisions -> O(1) lookups).\n- Uses the **same fields** that `equals` uses, combined so order matters\n  (`Objects.hash` \u002F the `31 * result + field` idiom).\n\n```java\n@Override public int hashCode() {\n  return Objects.hash(name, age);   \u002F\u002F good enough for almost everything\n}\n\u002F\u002F returning a constant is *legal* but degrades HashMap to O(n)\n```\n\n**Rule of thumb:** `Objects.hash(sameFieldsAsEquals)` — never a constant, never\na field excluded from `equals`.\n",{"id":82,"difficulty":30,"q":83,"a":84},"clone-vs-copy","What is wrong with Object.clone() and what is the alternative?","`clone()` is widely considered broken: it relies on the `Cloneable` marker\ninterface, bypasses constructors, does a **shallow** copy by default (shared\nmutable sub-objects), and has an awkward `protected`\u002Fchecked-exception design.\n\n```java\n\u002F\u002F Preferred: a copy constructor or static factory\nrecord Point(int x, int y) { }\nPoint copy = new Point(p.x(), p.y());          \u002F\u002F explicit, clear\n\nclass Box { Box(Box other) { \u002F* copy fields, deep where needed *\u002F } }\n```\n\n**Rule of thumb:** prefer a **copy constructor** or static factory (`copyOf`)\nover `clone()` — they're explicit, work with `final` fields, and let you control\nshallow vs deep copying.\n",15,null,{"description":11},"Java equals and hashCode interview questions — the equals\u002FhashCode contract, why you must override both, == vs equals, identity vs equality, getClass vs instanceof, Objects helpers, mutable keys, compareTo consistency and toString.","java\u002Foop\u002Fequals-hashcode","equals & hashCode","Object-Oriented Programming","oop","2026-06-19","U0sQgIK0X139rE6ovsi3Q5Ukeuz4U073XMsQhd3BUW4",[96,100,103,107,111],{"subtopic":97,"path":98,"order":99},"Classes & Objects","\u002Fjava\u002Foop\u002Fclasses-objects",1,{"subtopic":101,"path":102,"order":12},"Inheritance","\u002Fjava\u002Foop\u002Finheritance",{"subtopic":104,"path":105,"order":106},"Polymorphism","\u002Fjava\u002Foop\u002Fpolymorphism",3,{"subtopic":108,"path":109,"order":110},"Interfaces vs Abstract Classes","\u002Fjava\u002Foop\u002Finterfaces-vs-abstract",4,{"subtopic":90,"path":21,"order":20},{"path":113,"title":114},"\u002Fblog\u002Fjava-equals-hashcode-contract","Java equals & hashCode Contract — Identity, Equality, and Hash Collections",1782244116007]