[Java] Is it unnecessary to check "identity" in the implementation of the equals () method?

Introduction

Thank you for visiting. For Java's equals () method, I compared the execution time with and without the following implementation that immediately returns true if they are the same.

// equals()Identity check at the beginning of
if (this == obj){
	return true;
}

Ikisatsu (sorry for being long)

I am currently undergoing training as a new graduate SE of SIer. It's a little boring because it's based on the assumption that you're new to Java, but it's fun. (Although I have a sense of crisis that I have to study for myself even a little in the gap time ...)

Now, in the training, we are conducting development exercises. It is like a project experience such as unit, integration test, internal design document (component specification) creation, and coding based on the created external design document.

In the internal design, a flow chart of the method is created so that it can be coded based on the field name and method name that have already been decided. When I started working on a certain DTO specification, there ** "Override the equals () method" ** There was. Oh, this is going on ● I just did it in a seminar.

Override the equals () method

The equals () method is defined in the Object class as follows.

	//Excerpt from Java 11 source code
	public boolean equals(Object obj) {
		return (this == obj);
	}

This just returns identity, so you need to implement it properly in your own class. Since the equivalence in this case is determined by the specifications, for example, in the self-made class Person, even if the age field is different, if the name is the same, it is free to judge the equivalence (if you want to do it). キャプチャ.PNG

And here is the main subject of this article. The equals () method first checks for identity.

// equals()Identity check at the beginning of(Repost)
if (this == obj){
	return true;
}

That is, in the case of ```a.equals (a) `` `, true is returned immediately. This isn't required, but Eclipse's auto-generation says it's customary to implement it because it affects performance. Without this, it would be necessary to determine if the field of a is equal to the field of a.

What is this process?

When I made a flowchart of the equals () method and submitted it to the instructor who played the role of PM, I received the following comment in the relevant identity check process. ** "What is this process?" ** When implementing equals (), I thought it was a process to include, so I didn't think it would be entangled. Even if I put it in, I know the concept of identity check itself, and if I point out that "this time it is a small scale, so strict processing is not necessary", I can not help but "I do not know such processing, even in the field It doesn't make sense because I haven't seen it and the results returned are the same. " Of course, until recently, I'm a student and I don't know anything about the field, so maybe there is no identity check in the world ...? I became suspicious, and thought that this would be just a fool of writing redundant logic, so I wrote this article. For the time being, if I can realize the benefits of execution time, I will win (forced).

environment

Windows10 Eclipse

Method

Use the following Person.java. Originally, we had to override the equals () method of the Object class, but for comparison, we created equalsWithSelfCheck () with identity check and equalsWithoutSelfCheck () method without identity check and compared them. Both are based on the Eclipse auto-generated equals () method.

Person.java


public class Person {

	private String name;
	private int age;

	public Person(String name, int age) {
		this.name = name;
		this.age = age;
	}

	public boolean equalsWithoutSelfCheck(Object obj) {
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Person other = (Person) obj;
		if (age != other.age)
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}

	public boolean equalsWithSelfCheck(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Person other = (Person) obj;
		if (age != other.age)
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}
}

In addition, the difference in execution time is output with the same conditions in the following Main. It was measured 10 times repeatedly.

Main.java


public class Main {

	public static void main(String[] args) {
		ArrayList<Person> list = new ArrayList<>();
		Person person = new Person("Taro", 20);

		//A list that contains all the same person
		for(int i = 0; i < 10000000; i++) {
			list.add(person);
		}

		for (int i = 0; i < 10; i++) {
			long time1 = 0;
			long time2 = 0;

			for (Person p : list) {
				long start = System.nanoTime();
				person.equalsWithoutSelfCheck(p);
				long end = System.nanoTime();
				time1 = time1 + end - start;
			}

			for (Person p : list) {
				long start = System.nanoTime();
				person.equalsWithSelfCheck(p);
				long end = System.nanoTime();
				time2 = time2 + end - start;
			}

			System.out.println("Execution time difference:" + (time1 - time2) * 0.000001 + "millisecond");
		}
	}
}


result

Execution time difference: 7.8233999999999995 milliseconds
Execution time difference: 5.2443 ms
Execution time difference: 3.8985 milliseconds
Execution time difference: 4.9727 ms
Execution time difference: 5.5971 ms
Execution time difference: 2.7468 ms
Execution time difference: 10.9687 ms
Execution time difference: 5.1853 ms
Execution time difference: 5.4607 ms
Execution time difference: 3.6744 ms

In both cases, the method including the identity check gave faster results. There is some variation. Since the execution order may be the cause, I tried changing the order, but the execution time difference became negative and the same conclusion was reached.

By the way

I also tried the case where the contents of the list are equivalent but not the same as shown below.

		//All elements are equivalent(Not the same)list
		for(int i = 0; i < 10000000; i++) {
			list.add(new Person("Taro", 20));
		}

As a result, there was no average execution time difference as shown below.

Execution time difference: 3.5603 ms
Execution time difference:-0.223 ms
Execution time difference: 1.0935 ms
Execution time difference: 0.5618 ms
Execution time difference:-0.006999999999999999 milliseconds
Execution time difference:-1.4681 ms
Execution time difference:-0.8628 ms
Execution time difference: 1.5103 ms
Execution time difference:-1.9932999999999998 milliseconds
Execution time difference: 0.3394 ms

From this, it was confirmed that the identity check in the equals () method contributes sufficiently to the performance.

Conclusion

It was confirmed that the identity check in the equals () method contributed sufficiently to the performance, and it turned out to be a useful implementation. (My win (?))

at the end

Until the end Thank you for reading. If you have any questions, please let us know and give us your guidance.

Recommended Posts

[Java] Is it unnecessary to check "identity" in the implementation of the equals () method?
The milliseconds to set in /lib/calendars.properties of Java jre is UTC
Static function to check if the RGB error of BufferdImage is within the specified ratio in Java
[Java] Handling of JavaBeans in the method chain
[Java] Where is the implementation class of annotation that exists in Bean Validation?
Is it mainstream not to write the closing tag of <P> tag in Javadoc?
The comparison of enums is ==, and equals is good [Java]
Implementation of tri-tree in Java
[Java] When putting a character string in the case of a switch statement, it is necessary to make it a constant expression
How to get the class name / method name running in Java
Easy way to check method / field list in Java REPL
Command to check the number and status of Java threads
[Android, Java] Convenient method to calculate the difference in days
Create a method to return the tax rate in Java
How to derive the last day of the month in Java
[Ruby] Thinking when there is no receiver in front of the method (it looks like)
Implementation of like function in Java
Call the super method in Java
It doesn't respond to the description in .js of the packs file
[Note] Java: Is it necessary to override equals for equality judgment?
How to check for the contents of a java fixed-length string
Investigation method when the CPU of the server running java is heavy
How to get the length of an audio file in java
How to increment the value of Map in one line in Java
Method definition location Summary of how to check When defined in the project and Rails / Gem
Graph the sensor information of Raspberry Pi in Java and check it with a web browser
[Java beginner] Conversion from character string to numerical value-What is the parseInt method of the Integer class? ~
Implementation of clone method for Java Record
My thoughts on the equals method (Java)
Implementation of DBlayer in Java (RDB, MySQL)
How to set the indent to 2 single-byte spaces in the JAXB implementation of the JDK
Check the contents of the Java certificate store
The story of forgetting to close a file in Java and failing
[Java] How to compare with equals method
[Java Servlet] The road of Senri is also one step to the first
The identity of params [: id] in rails
[Java] How to use the toString () method
Memo: [Java] If a file is in the monitored directory, process it.
Get the type of an array element to determine if it is an array
This and that of the implementation of date judgment within the period in Java
Comparison of thread implementation methods in Java and lambda expression description method
How to find the total number of pages when paging in Java
How to get the date in java
Output of the book "Introduction to Java"
How to get the absolute path of a directory running in Java
[Java] Output the result of ffprobe -show_streams in JSON and map it to an object with Jackson
From Java9, the constructor of the class corresponding to primitive types is deprecated.
The story of writing Java in Emacs
Android development, how to check null in the value of JSON object
[Java] Check the number of occurrences of characters
[Java] Check if the character string is composed only of blanks (= Blank)
What is CHECKSTYLE: OFF found in the Java source? Checkstyle to know from
Is it possible to put the library (aar) in the Android library (aar) and use it?
When I wanted to create a method for Premium Friday, it was already in the Java 8 standard API
I received the data of the journey (diary application) in Java and visualized it # 001
How to check the latest version of io.spring.platform to describe in pom.xml of Spring (STS)
Summarize the life cycle of Java objects to be aware of in Android development
Make the JSON of the snake case correspond to the field of the camel case in Java (JVM)
Let's refer to C ++ in the module of AndroidStudio other project (Java / kotlin)
Validate the identity token of a user authenticated with AWS Cognito in Java
Retrieve the first day of week in current locale (what day of the week is it today?)