== — compares memory references. equals() — compares content or logical equality.Vivid analogy: Two identical teddy bears in different stores. == asks "Is this the exact same physical teddy bear?" (No — different stores). .equals() asks "Are these teddy bears identical?" (Yes — same color, size, features).Why it matters: This distinction causes more bugs than almost any other Java concept. Using == for objects leads to intermittent failures — especially with Strings where pooling behavior makes == work sometimes.For primitives:javaint a = 100;int b = 100;a == b; // true — compares actual values// Primitives don't have .equals()For objects:javaString s1 = new String("hello");String s2 = new String("hello");s1 == s2; // false — different objects on heaps1.equals(s2); // true — same character contentString pool gotcha:javaString s1 = "hello"; // String pool (shared)String s2 = "hello"; // Reuses same pool references1 == s2; // true!String s3 = new String("hello"); // New objects1 == s3; // falses1.equals(s3); // trueBest practice: Always use .equals() for content comparison. Reserve == for null checks and enum identity.