Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Java Comparison Mechanics: `==` Operator versus `equals()` Method

Tech 1

In Java, determining equality involves distinct mechanisms depending on whether one is comparing primitive values or object references. The == operator and the equals() method serve different purposes in this context.

The == Operator

The == operator functions as a binary comparison mechanism. For primitive data types (such as int, char, boolean), it evaluates whether the actual values stored in the variables are identical.

int val1 = 100;
int val2 = 100;
System.out.println(val1 == val2); // true, since values match

When applied to objects, == performs a reference comparison. It checks if two variables point to the exact same memory address in the heap. Even if two objects contain identical atttributes, == returns false if they are distinct instances.

String str1 = new String("demo");
String str2 = new String("demo");
System.out.println(str1 == str2); // false, distinct memory locations

String str3 = "demo";
String str4 = "demo";
System.out.println(str3 == str4); // true, both refer to the same string constant pool instance

The equals() Method

The equals() method, defined in the Object class, is intended for content comparison. By default, the Object class implementation simply uses the == operator, effectively comparing references.

public boolean equals(Object obj) {
    return (this == obj);
}

However, many classes in the Java Standard Library, such as String, Integer, and Date, override this method to compare the actual data within the objects.

String data1 = new String("sample");
String data2 = new String("sample");
System.out.println(data1.equals(data2)); // true, character sequences match

Integer int1 = new Integer(50);
Integer int2 = new Integer(50);
System.out.println(int1.equals(int2)); // true, integer values match

When overriding equals(), one must adhere to a specific contract to ensure consistent behavior:

  1. Reflexive: An object must equal itself.
  2. Symmetric: If a.equals(b) is true, then b.equals(a) must be true.
  3. Transitive: If a.equals(b) and b.equals(c) are true, then a.equals(c) must be true.
  4. Consistent: Multiple invocations must return the same result, provided the object state remains unchanged.
  5. Non-null: Any non-null reference must return false when compared to null.

Implementation Example

Below is an implementation of a User class that overrides equals to compare based on the id and username fields. The hashCode() method is also updated to maintain the contract that equal objects must have equal hash codes.

import java.util.Objects;

public class User {
    private final int id;
    private final String username;

    public User(int id, String username) {
        this.id = id;
        this.username = username;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null || this.getClass() != obj.getClass()) {
            return false;
        }
        User other = (User) obj;
        return this.id == other.id && Objects.equals(this.username, other.username);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, username);
    }

    public static void main(String[] args) {
        User userA = new User(101, "admin");
        User userB = new User(101, "admin");
        User userC = userA;

        System.out.println(userA == userB);       // false, different references
        System.out.println(userA.equals(userB));  // true, identical content
        System.out.println(userA == userC);       // true, same reference
        System.out.println(userA.equals(userC));   // true, same reference implies same content
    }
}
Tags: JavaEquality

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.