Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How do I use equals ()? HashCode ()?

2025-01-19 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/03 Report--

This article mainly explains "how to use equals ()? =? hashCode ()?". The explanation in the article is simple, clear and easy to learn and understand. Please follow the editor's train of thought to study and learn "how to use equals ()? =? hashCode ()?" Come on!

Catalogue

Data types in Java

When to use the relational operator = = and when to use the equals method?

Equals method, why a null pointer java.lang.NullPointerException is reported?

What is the function of hashCode method? what is the relationship between hashCode and equals?

Why does the hashCode method have to be overridden in every class that overrides the equals method?

Data type

The data types in java can be divided into two categories:

1. Basic data type (original data type)

Byte,short,char,int,long,float,double,boolean the comparison between them, using a double equal sign (= =), and the underlying data type compares their values.

two。 Reference types (classes, interfaces, arrays)

When they compare with (= =), they compare their storage address in memory, the object is placed in the heap, and the reference (address) of the object is stored in the stack. Thus it can be seen that'= 'compares the address values in the stack when the compared object is a reference type.

Relational operator = =

The relational operators included in java are less than (), less than or equal to (=), equal to (= =), and not equal to (! =).

= = and! = apply to all objects, but these two operators usually have problems when comparing objects:

Here = = and! = compare references to objects. Although the content of the object is the same, the reference to the object is different, so n1==n2 is false.

Integer N1 = new Integer (47); Integer N2 = new Integer (47); System.out.println (N1 = = N2); / / false System.out.println (N1! = N2); / / true

Here = = compares the basic data types, then he will compare whether the values are equal. So at this point N1 = = N2 outputs true.

Int N1 = 100; int N2 = 100; System.out.println (N1 = = N2); / / true System.out.println (N1! = N2); / / false

Equals method

By default, the object's equals method calls the equals method in the Object class. The source code is as follows

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

Note that the = = is still used here, where the reference object is compared, so the comparison address (whether it is the same object)

In the second case, the object's equals method is overridden. For example, the String object. The source code is as follows

Public boolean equals (Object anObject) {if (this = = anObject) {return true;// if it is the same object directly returns} if (anObject instanceof String) {/ / is the String object to start judging the content. String anotherString = (String) anObject; int n = value.length; if (n = = anotherString.value.length) {char v1 [] = value; char v2 [] = anotherString.value; int I = 0 While (nMel -! = 0) {/ / character by character comparison. If there are unequal characters, return false if (v1 [I]! = v2 [I]) return false; iTunes;} return true }} return false;}

At this point, the rewriting implementation of the equals method is different, but after rewriting, it is generally based on whether the contents of the object are equal to determine whether the object is equal. For most Java class libraries, the equals () method is implemented to compare the contents of the object rather than the reference to the object.

Avoid equals methods and report null pointers

To avoid equals method reported null pointer, first tell you that the answer is to use Objects.equals (aforme b), added an Objects utility class in JDK7, it provides some methods to manipulate the object, it consists of some static practical methods, these methods are null-save (null pointer security) or null-tolerant (null pointer tolerance), used to calculate the hashcode of the object, return the string representation of the object, and compare the two objects.

By default, the object's equals method is not overridden to call the equals method in the Object class

So let's write an example of reporting an error:

An a = null;// assume that I receive a config object, and I don't know if it's empty, so compare boolean r = a.equals (new B ()); System.out.println (r); / / output java.lang.NullPointerException

At this time, due to our carelessness, we did not check the parameters after receiving the parameters, resulting in calling the equals method to report a null pointer.

/ / other examples are: null.equals ("java Treasure Book"); / / NullPointerException "java Treasure Book" .equals (null); / / false results null.equals (null) only if the object on the left side of equals is not Null; / / NullPointerException

Use Objects.equals (a Null b), the left and right sides are Null, and the pointer will not be null.

Objects.equals (null, java); / / false Objects.equals (java, null); / / false Objects.equals (null,null); / / true

Take a look at the source code of the Objects.equals method, which tolerates null pointers

Public static boolean equals (Object a, Object b) {return (a = = b) | (a! = null & & a.equals (b));}

HashCode () method

Hash is actually a person's name, because he proposed the concept of a hash algorithm, so it was named after him. Hashing algorithm, also known as hashing algorithm, refers to assigning data to an address directly according to a specific algorithm. Popular understanding is a method of creating small digital "fingerprints" from any kind of data.

In java, by default, the object does not override the hashCode () method. Is used in the Object class.

Public native int hashCode (); / / it is a native method.

The hashCode method defined by the Object class returns different integers for different objects. (this is achieved by converting the internal address of the object to an integer.)

Example:

Config config1 = new Config (); Config config2 = new Config (); System.out.println (config1.hashCode ()); / / 1128032093 System.out.println (config2.hashCode ()); / / 1066516207 System.out.println (config1.equals (config2)); / / false

The relationship between hashCode and equals

Both are methods in the Object class, and since the Object class is the base class for all classes, these two methods can be overridden in all classes.

Principle 1: if x.equals (y) returns "true", then the hashCode () of x and y must be equal

Principle 2: if x.equals (y) returns "false", then the hashCode () of x and y may be equal or unequal.

Principle 3: if the hashCode () of x and y are not equal, then x.equals (y) must return "false"

Principle 4: generally speaking, the equals method is called by the user, but the hashcode method is not called by the user.

Principle 5: when an object type is an element of a collection object, the object should have its own equals () and hashCode () designs and follow the principles mentioned earlier.

During the execution of a Java application, when the hashCode method is called multiple times on the same object, the same integer must be returned consistently, provided that the information used to compare the object for equals has not been modified. The integer does not need to be consistent from one execution of an application to another execution of the same application.

If two objects are equal according to the equals (Object) method, calling the hashCode method on each of the two objects must produce the same integer result.

If two objects are not equal according to the equals (java.lang.Object) method, calling the hashCode method on either of the two objects does not necessarily produce different integer results. However, programmers should be aware that generating different integer results for unequal objects can improve the performance of hash tables.

Why does the hashCode method have to be overridden in every class that overrides the equals method?

In every class that overrides the equals method, the hashCode method must also be overridden. Failure to do so will violate the general convention of Object.hashCode and prevent the class from working properly with all hash-based collections

Above we introduced what hashCode is, to further understand the application of hashCode, we must first understand the containers in Java, because HashCode is only useful in data structures that need to use hash algorithms, such as HashSet, HashMap.

Let's take hashMap as an example:

HashMap is a structure for storing data consisting of arrays and linked lists. To determine where a data is stored in the array is to use the hashCode method to calculate where it is stored. If there is a conflict, the equals method will be called for comparison. If it is different, it will be added to the end of the linked list, and if it is the same, the original data will be replaced. Of course, the location is not calculated by a simple hashCode method above, and there are some other steps. Here, you can simply think that hashCode determines the location. The code is as follows:

Public V put (K key, V value) {/ / initialize if (table = = EMPTY_TABLE) {/ / initialize the hash table inflateTable (threshold) if the hash table is not initialized } / / when key is null, call the putForNullKey method to save the null in the first location of table, which is why HashMap allows it to be null. If (key = = null) {return putForNullKey (value);} / / calculate the hash value of key int hash = hash (key) / / navigate to the specified slot of the entry array int I = indexFor (hash, table.length) according to the hash value of key and the length of the array; / / get the entry on the storage location, and if the entry is not empty, traverse the linked list for (Entry e = table [I]; e! = null; e = e.next) {Object k / determine whether key exists by key's hashCode and equals methods. If so, replace the old value with the new value and return the old value if (e.hash = = hash & & (k = e.key) = = key | | key.equals (k)) {V oldValue = e.value; e.value = value; e.recordAccess (this) Return oldValue;}} / / increase the number of modifications by 1 modCount++; / / if the linked list cannot be found or if key does not exist after traversing the linked list, create a new Entry and add it to the HashMap addEntry (hash, key, value, I); return null;}

In the above method, when you call a method, you can see that the subscript of the array is determined by XOR with a specific value based on the return value of the hashCode method of the passed element:

Static int indexFor (int h, int length) {/ / A pair of hash values and length-1 to calculate the index return h & (length-1);}

Back to our question: why does the hashCode method have to be overridden in every class that overrides the equals method?

If you rewrite equals, and the implementation of hashCode is not overridden, then the hashcode method of the class is the default hashcode method of Object. Because the default hashcode method is a value obtained by the hash algorithm based on the memory address of the object, it is very likely that two objects are obviously "equal", but hashCode is not the same.

In this way, when you use one of them as a key to save to hashMap, hasoTable or hashSet, and then use "equal" to find the other as the key value to find them, you can't find them at all. Lead to HashSet, HashMap can not operate normally.

For example, there is a class A that overrides the equals method, but does not override the hashCode method. Object A1 and object A2 use the equals method to be equal. According to the above hashcode usage, then the hashcode of both of them must be equal, but here because the hashcode method is not rewritten, their two hashcode are not the same. So, after rewriting the equals method, we try to rewrite the hashcode method, through a certain algorithm, to make them when the equals is equal. There will be the same hashcode value.

Summary

= when comparing basic data types, the values are compared

= when comparing reference data types, the reference address of the object is compared

The equals method of the object, without overriding, uses = = and compares the reference address of the object

The equals method of the object, after rewriting, is used to compare whether the contents of the object are equal. The implementation can use IDE generation or custom implementation. (for example, the String class overrides the equals method by comparing characters one by one.)

In the case of not overriding, the equals method of the object calls the equals method in the Object class, and a null pointer is reported when the condition is Null to the left. Using Objects.equals (amemb) can avoid null pointers.

Hashcode is used by the system to retrieve objects quickly.

After rewriting the equals method, you should also rewrite the hashcode method, otherwise it will cause HashSet, HashMap and other hashCode-dependent containers not to function properly.

Thank you for reading. The above is "how to use equals ()? =? hashCode ()?" After the study of this article, I believe you on how to use equals ()? HashCode ()? This problem has a deeper understanding, the specific use of the situation still needs to be verified by practice. Here is, the editor will push for you more related knowledge points of the article, welcome to follow!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report