Problems role of Java in HashCode () and equals () is Java hashCode () and equals () answers

introduction  

  We know that in Java collection (Collection) can be roughly divided into two categories, one category is List, then there is a class Set.

  Elements within the former set is ordered, the element can be repeated; disorder latter element, but the element can not be repeated.

  Here it begs the question: To ensure the element does not repeat what should be the basis to judge it?

Why hashCode ()?

       In order to solve the problem into duplicate data, beginning developers have thought of using Object.equals method.

  However, they soon found that if each additional element to check once, when a lot of elements, after adding to the number of elements in a set of relatively very much.

  That is, if the collection now has 1000 elements, then the first 1001 elements to the collection, it is necessary to call the equals method 1000. This obviously will greatly reduce efficiency.

       So, Java uses the principle of the hash table. Hash (Hash) actually is a personal name, because he put forward the concept of "hash algorithm", so named to his name.

  Also known hash algorithm hash algorithm, the hash value is also called a hash code, in fact the data directly to a designated address in accordance with the hash algorithm.

  Beginners can simply understood, hashCode method actually returns the physical address of the object is stored (actually probably not).  

       Thus, when a new set of elements to be added, before calling the hashCode method of this element, once it is positioned to a physical location can be placed on it.

  If there is no element in this position, it can be stored directly in this position, we do not have any comparison of;

  If you already have an element of this position, it is calling its equals method to compare with new elements, the same words do not exist, and it is not the same as the other hash address.

  So there is a conflict resolution problem here. As a result the actual number of calls equals method is greatly reduced, almost need only once or twice.

 

The role of the two methods

equals () action: means for determining whether the object is the same as other objects;

  Object class is defined equals ():

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

  Obviously, the comparison of the Object class native code is a reference to an address, but need to be reminded that in String, Math, Integer, Double, etc. wrapper classes are all equals () with varying degrees of rewriting to meet their different needs , for example in the String class:

public boolean equals(Object anObject) {  
    if (this == anObject) {  
        return true;  
    }  
    if (anObject instanceof String) {  
        String anotherString = (String)anObject;  
        int n = count;  
        if (n == anotherString.count) {  
            char v1[] = value;  
            char v2[] = anotherString.value;  
            int i = offset;  
            int j = anotherString.offset;  
            while (n– != 0) {  
                if (v1[i++] != v2[j++])  
                    return false;  
            }  
            return true;  
        }  
    }  
    return false;  
}  

  Obviously, equals the String class () address comparison is no longer a reference to the object itself but, in Java8 basic data types equals () to compare the contents are, in fact, value.

 

HashCode () function: return to the different objects different hash code values, corresponding to the identification code;

  When using HashCode () shall meet the following three points:

  1. During the execution of a Java application, if an object to provide a comparison of equals information has not been modified, then the object no matter how many times calling hashCode () must always return the same integer;
  2. If two objects according equals (Object) method are equal, then calling the two respective hashCode () must produce the same result integer;
  3. Two object calls equals (java.lang.Object) Method result is not equal, each call both hashCode () is not necessarily the same, may be the same, may be different. 

 

Emphasis

   Look at the collection, use hashcode undoubtedly greatly reduce the number of object comparison, improve search efficiency!

  eqauls and hashCode methods of Java objects is such a requirement:

    1, is equal to (the same) object must have equal hash code (or hash code).

    2, the same hashCode if two objects are not necessarily the same.

 

Possible confusion

  First, the objects are equal (same) must have equal hash code (or hash code), and why?

  When A and B are assumed to be equal two objects, i.e. the result of their equals true, but they are not the same each hash code, but they are the same to be stored in the HashMap, because there might result in a different hash code calculated HashMap position out of the internal array index is not the same, then a, B is likely to also store the same in a HashMap, but we know that HashMap is not allowed to store duplicate elements.

   Second, why two objects have the same hashCode they are not necessarily the same?

  Your question is actually saying hashCode different objects may have the same reasons for this result I personally think it is due to the "hash algorithm" resulting in the production of hash code, two objects have in some ways highly consistent sex. Establish a new list will position index in the hash code of the specified internal array of positive considering that might be the case, so HashMap hashCode add two identical objects, and then string together two objects at that location, so that it can ensure the same can still be stored in HashMap hashCode although, of course, if they call equals () returns a value of false.

  Added to that, there is a special term to describe this phenomenon, we called hash collision, it is clear that the industry, although the hash conflict can be solved, but no one will want to see it often.

 

Actual operation

  In the actual coding process, we often will be asked to rewrite the hashCode () and equals (), I also have this question puzzling, but now I can explain the secret of which to everyone.

  To HashSet example, we know that HashSet is inheriting the Set interface, and implements the Set interface Collection interface, HashSet not allowed duplicate values, but also the position of the element of uncertainty.

  So here you tell us about the Java collection to determine whether two objects are equal rules:

    1. First determination hashCode two objects are equal;

      If they are equal, then into the second step is determined;

           If not equal, then the two objects are not considered equal, the end of the judgment.

    2. Analyzing with two objects are equal equals ().

      If this judgment is also equal, then the two objects are considered equal;

      If not equal, then the two objects are not considered equal.

Why should we judge it twice?

  It may not be determined for the first time, but if not, the actual efficiency will be greatly reduced, especially when compared to making large amounts of data. In fact, in front of introducing hashCode () that reference, i.e. hashCode () equal, the equals () may not be equal, so we added a second determination to be limiting. In general, the first judgment is not possible, but must be the second determination, but the two are preferably written in the actual development, large amounts of data need to judge once appear alone equals () judgment then the efficiency will be greatly reduced.

 

Code Display

package Exercise;
import java.util.HashSet; public class e1 { public static void main(String[] args) { HashSet hs=new HashSet(); hs.add(new Student(1,"张三")); hs.add(new Student(2,"李四")); hs.add(new Student(3,"王麻子")); hs.add(new Student(1,"张三")); for (Object object : hs) { System.out.println(object); } } } class Student{ int num; String name; Student(int num,String name){ this.name=name; this.num=num; } public String toString(){ return num+":"+name; } }

  operation result:

  

  Why Hashset added equal elements of it, and this is not contrary to the principle of Hashset it? The answer is: no. Because when () on the establishment of two new Student (1, "Joe Smith") object to be compared according to hashCode, generating a different hash code value, so Hashset to treat him as a different object, of course, this when the value equals () method returns is not so.

        Why would generate a different hash code value it? The reason is that write our own Student class does not re-own hashCode () and equals () method, so in comparison, is inherited object class hashCode (), and hashCode object class () is a local the method of comparison is the address (reference address) object, create an object using a new method to generate two different objects, of course, the result is that the two objects hashCode () returns the value is not the same, so will Hashset treat them as different objects.

        How to solve this problem? The answer is: override the hashCode () and equals () method in the Student class.

package Exercise;

import java.util.HashSet;

public class e1 {
	public static void main(String[] args) {
		HashSet hs=new HashSet();
		hs.add(new Student(1,"张三"));
		hs.add(new Student(2,"李四"));
		hs.add(new Student(3,"王麻子"));
		hs.add(new Student(1,"张三"));
		for (Object object : hs) {
			System.out.println(object);
		}
	}
}
class Student{
	int num;
	String name;
	Student(int num,String name){
		this.name=name;
		this.num=num;
	}
	
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		result = prime * result + num;
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Student other = (Student) obj;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		if (num != other.num)
			return false;
		return true;
	}

	public String toString(){
		return num+":"+name;
	}
}

  operation result

  

  You can see the problem of repetitive elements have been eliminated, according to rewrite the method, even if two calls to the new Student (1, "Joe Smith"), we get the hash code of the object, the method according to rewrite hashCode () get the hash code must be the same, of course, according to the equals () method we can determine is the same, so when you add them to the collection hashset as repeating elements to look up.

  Just use rewrite is done with the shortcut keys, we can hand to knock, but write so much is not necessary.

Hand knock rewriting the code:

public int hashCode(){
      return num * name.hashCode();
 }
 public boolean equals(Object o){
      Student s = (Student) o;
      return num == s.num && name.equals(s.name);
 }

 

To be summed up

  1.   Focus is on equals, hashCode just rewrite technical requirements (for efficiency);
  2.   Why override equals what? Because Java collection framework is judged by whether the two objects are equal equals;
  3.   In hibernate often used to store a collection of related objects set, and the set of sets are not allowed to repeat. When you add elements to the HashSet collection, in fact, as long as the rewrite equals () this one will do. But hashset elements relatively long time, or rewrite equals () method is complicated when we only compare judgment equals () method, the efficiency will be very low, so the introduction of the hashCode () This method is simply to increase the efficiency, and this is very necessary.

  If hashCode () write:

int the hashCode public () {   
   return. 1; // Invalid equivalent hashcode   
}

  The effect of this is that when comparing the hash code can not be determined, because each object returned hash code is 1, each must go through in order to judge whether or not the comparison equals repeat after () method, which will of course cause efficiency is greatly reduced.

 

Reference article:

Proper use of equals in Java () and hashCode () method

In Java equals () and hashCode () method Detailed

Application-depth analysis of the underlying data structure of Java objects and hashCode hashCode in a HashMap

Issues Java hashCode () and equals () answers

Guess you like

Origin www.cnblogs.com/SUN99bk/p/11660976.html