Lesson 6 | Testing for equality |
Objective | Describe equality operators and equals() method |
Testing equality in Java using Operators
In Java, comparing objects for equality can be done using the equality operators (`==` and `!=`) and the `equals()` method. Each has its own purpose and behavior:
- Equality Operators (`==` and `!=`):
- Usage: The equality operators `==` and `!=` are used to compare the references of two objects, not the actual content of the objects.
- Behavior:
- `==`: Returns `true` if both references point to the same object in memory.
- `!=`: Returns `true` if the references point to different objects in memory.
Example:
String str1 = new String("hello");
String str2 = new String("hello");
String str3 = str1;
System.out.println(str1 == str2);
// false, because str1 and str2 are different objects
System.out.println(str1 == str3);
// true, because str1 and str3 refer to the same object
- The `equals()` Method:
- Usage: The `equals()` method is used to compare the actual content (state) of two objects.
- Behavior:
- By default, the `equals()` method in the `Object` class behaves the same as `==`, comparing references.
- Many classes (e.g., `String`, `Integer`) override the `equals()` method to compare the values of the objects.
Example with `String`:
String str1 = new String("hello");
String str2 = new String("hello");
System.out.println(str1.equals(str2));
// true, because the content of str1 and str2 is the same
Custom `equals()` Method
When creating custom classes, it's common to override the `equals()` method to define meaningful equality based on the object's state.
Example of Overriding `equals()`:
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null || getClass() != obj.getClass()) {
return false;
}
Person person = (Person) obj;
return age == person.age && name.equals(person.name);
}
public static void main(String[] args) {
Person person1 = new Person("Alice", 30);
Person person2 = new Person("Alice", 30);
Person person3 = new Person("Bob", 25);
System.out.println(person1.equals(person2)); // true, because name and age are the same
System.out.println(person1.equals(person3)); // false, because name and age are different
}
}
Summary
- Equality Operators (`==` and `!=`):
- Compare object references.
- Useful for checking if two references point to the same object.
- `equals()` Method:
- Compares object content.
- Should be overridden in custom classes to define meaningful equality based on object state.
Understanding the difference between these two methods of comparison is crucial for correctly implementing equality checks in Java.
Java Equality Operator
The equality operators
==
and
!=
are used with both primitive types and object references.
They return a
boolean
value indicating whether or not the operands are "equal." When testing for equality, you should keep the following important points in mind:
- Numeric values are promoted before being compared.
- Numeric values cannot be compared to
boolean
values.
- Object references are checked to see if they refer to the same object and not whether they have the same value.
- The
equals()
method should be used to determine whether two objects have the same values.
The first rule is important because it allows any numeric value to be compared to any other numeric value. You will probably see some exam questions that will require you to know this. Keep the second rule in mind in case you see a numeric value being compared to a boolean value. You will definitely see questions related to the last two rules.
The
equals()
method of the
Object
class is extended by subclasses to allow objects to be compared based on their values.
One of the exam objectives requires you to be able to determine the results of comparing
String
,
Boolean
, and
Object
objects using the
equals()
method. If a program contains two
String
objects
s1
and
s2
with equal values,
s1.equals(s2)
returns true. However, the following
s1 == s2
will return true if and only if
s1
and
s2
reference the same object in memory.
The following question will deepen your understanding of the equals() method in Java.
Scenario: Assume that a, b, and c refer to instances of primitive wrapper classes.
Question: Which of the following statements are correct?
- a.equals(a) will always return true.
- b.equals(c) may return false even if c.equals(b) returns true.
- a.equals(b) returns same as a == b.
- a.equals(b) throws an exception if they refer to instances of different classes
- a.equals(b) returns false if they refer to instances of different classes.
Answer: 1, 5
Explanation:
3. The wrapper classes's equals() method overrides Object's equals() method to compare the actual value instead of the reference.
4. It returns false in such a case.
The equals() method of a primitive wrapper class contains the characteristics of an
equivalence relation.
Equals method of a primitive wrapper class (i.e. java.lang.Integer, Long, Double, Float etc) are
- reflexive => a.equals(a) return true.
- symmetric => a.equals(b) returns the same result as b.equals(a)
- transitive => if a.equals(b) and b.equals(c) return true, then a.equals(c) returns true.
For option 1 for the question above contains the reflexive property.