Home PC Games Linux Windows Database Network Programming Server Mobile  
           
  Home \ Programming \ The hashcode method of Java     - Linux beginners to develop the seven habits (Linux)

- PostgreSQL 9.4.3 Installation and Configuration under CentOS 6.5 (Database)

- Android basics summary article (Programming)

- Examples 14 grep command (Linux)

- Java abstract class instantiation (Programming)

- Oracle 11g on Linux system boot from the startup settings (Database)

- Hadoop 2.7.1 Installation and Configuration under RedHat Linux 6.5 (Server)

- Zabbix monitoring platform to extract a single server graphical Python implementation of concurrent (Server)

- 14 useful example Linux Sort command (Linux)

- Fedora network set up simple (Linux)

- Installation of Gitlab under Ubuntu (Linux)

- Sudo and Root Account in Ubuntu related (Linux)

- Oracle common internal event tracking number (Database)

- Mounting kit under Fedora Linux (Linux)

- Build Python3.4 + PyQt5.3.2 + Eric 6.0 development platform Ubuntu 14.04 (Server)

- Linux package management (Linux)

- To install Scribus 1.4.4 under ubuntu (Linux)

- Oracle users to automatically increase the partition table (Database)

- Confrontation dragged Library - Web front-end encryption slow (Linux)

- Zabbix monitoring tool deployment under Ubuntu server (Server)

 
         
  The hashcode method of Java
     
  Add Date : 2018-11-21      
         
         
         
  The hash table data structure presumably most people are not familiar with, but also to improve the search efficiency in many places will use to hash table. There is a method in Java's Object class:

public native int hashCode ();

According to a statement of this method shows that the method returns a value of type int, and is a local method, so the Object class and did not give a specific implementation.

Why the need for such a method of the Object class? What does it do it? Today we'll explore specific hashCode methods.

A method of action .hashCode

For the programming language includes the container type, it will basically involve hashCode. In Java, too, the main role hashCode method is to tie together a collection of hash-based normal operation, this set includes a hash HashSet, HashMap and HashTable.

Why do you say? Consider a situation when inserting objects to the collection, how to determine whether the object already exists in the collection? (Note: the collection does not allow duplicate elements exist)

Perhaps most people would think of calling equals method to compare one by one, this method does work. But if ten thousand or more data collection data already exists, if the equals method to compare one by one, the efficiency is necessarily a problem. In this case the role of the hashCode method is manifested when the collection you want to add a new object, call the object's hashCode method to obtain a hashcode value corresponding to actually use a table stored in the implementation of HashMap has deposit into hashcode value of an object, if the table is not the hashcode value, it can direct deposit into, without any further comparison; if the hashcode value exists, it calls its equals method to compare with new elements, if not the same saved, not the same as other addresses on the hash, so here there is a conflict resolved, so that the actual number of calls equals method is greatly reduced, and said plainly: Java hashCode method is in accordance with certain rules object-related information (such as memory address of the object, field object, etc.) mapped to a value, this value is referred to as a hash value. The following code is the implementation java.util.HashMap's put method:

public V put (K key, V value) {

        if (key == null)

            return putForNullKey (value);

        int hash = hash (key.hashCode ());

        int i = indexFor (hash, table.length);

        for (Entry < K, V> e = table [i]; e = null;! e = e.next) {

            Object k;

            if (e.hash == hash && ((k = e.key) == key || key.equals (k))) {

                V oldValue = e.value;

                e.value = value;

                e.recordAccess (this);

                return oldValue;

            }

        }

        modCount ++;

        addEntry (hash, key, value, i);

        return null;

    }

put method is used to add new elements to a HashMap, seen from the realization put method will first call hashCode methods hashCode value of the element, and then see if the hashCode value table exists, if there is a method to re-call equals to determine whether the presence of the element, if it exists, is updated value value, otherwise it will add a new element to the HashMap. As can be seen from here, there is a hashCode method is to reduce the number of calls equals method to improve program efficiency.

Some people mistakenly think that by default, hashCode returns the memory address of the object is, in fact, this view is not comprehensive, and indeed some JVM in the realization of the object is returned directly to the memory address, but most of the time is not the case, only He said memory address may have some relevance. Here is the HotSpot JVM to generate hash hash value:

static inline intptr_t get_next_hash (Thread * Self, oop obj) {

  intptr_t value = 0;

  if (hashCode == 0) {

    // This form uses an unguarded global Park-Miller RNG,

    // So it's possible for two threads to race and generate the same RNG.

    // On MP system we'll have lots of RW access to a global, so the

    // Mechanism induces lots of coherency traffic.

    value = os :: random ();

  } Else

  if (hashCode == 1) {

    // This variation has the property of being stable (idempotent)

    // Between STW operations. This can be useful in some of the 1-0

    // Synchronization schemes.

    intptr_t addrBits = intptr_t (obj) >> 3;

    value = addrBits ^ (addrBits >> 5) ^ GVars.stwRandom;

  } Else

  if (hashCode == 2) {

    value = 1; // for sensitivity testing

  } Else

  if (hashCode == 3) {

    value = ++ GVars.hcSequence;

  } Else

  if (hashCode == 4) {

    value = intptr_t (obj);

  } Else {

    // Marsaglia's xor-shift scheme with thread-specific state

    // This is probably the best overall implementation - we'll

    // Likely make this the default in future releases.

    unsigned t = Self -> _ hashStateX;

    t ^ = (t < < 11);

    Self -> _ hashStateX = Self -> _ hashStateY;

    Self -> _ hashStateY = Self -> _ hashStateZ;

    Self -> _ hashStateZ = Self -> _ hashStateW;

    unsigned v = Self -> _ hashStateW;

    v = (v ^ (v >> 19)) ^ (t ^ (t >> 8));

    Self -> _ hashStateW = v;

    value = v;

  }

  value & = markOopDesc :: hash_mask;

  if (value == 0) value = 0xBAD;

  assert (! value = markOopDesc :: no_hash, "invariant");

  TEVENT (hashCode: GENERATE);

  return value;

}

The implementation is located in the hotspot / src / share / vm / runtime / synchronizer.cpp file.

So some people will say, according to hashcode value can determine whether two objects are equal it? It is certainly not possible because different objects may generate the same hashcode value. Although it can not determine whether two objects are equal according to hashcode value, but can be based directly on the two objects ranging hashcode value judgment, if the value of the two objects ranging hashcode, then there must be two different objects. To determine if two objects are really the same, must be equals method.

That is for two objects, if you call the result obtained by the method equals true, the two hashcode value of the object must be equal;

If the results obtained by the method equals false, the hashcode value of the two objects are not necessarily different;

If the value of the two objects ranging hashcode, equals the result obtained by the method is necessarily false;

If hashcode value of the two objects are equal, the result equals methods unknown.

Two .equals and hashCode methods

In some cases, the program designer in the design of a class when the need to override equals methods, such as the String class, but do pay attention, while rewriting the equals method, you must override hashCode methods. Why do you say?

Let's look at an example:

package com.cxh.test1;

import java.util.HashMap;

import java.util.HashSet;

import java.util.Set;

class People {

    private String name;

    private int age;

   

    public People (String name, int age) {

        this.name = name;

        this.age = age;

    }

   

    public void setAge (int age) {

        this.age = age;

    }

       

    @Override

    public boolean equals (Object obj) {

        // TODO Auto-generated method stub

        return this.name.equals (((People) obj) .name) && this.age == ((People) obj) .age;

    }

}

public class Main {

    public static void main (String [] args) {

       

        People p1 = new People ( "Jack", 12);

        System.out.println (p1.hashCode ());

           

        HashMap < People, Integer> hashMap = new HashMap < People, Integer> ();

        hashMap.put (p1, 1);

       

        System.out.println (hashMap.get (new People ( "Jack", 12)));

    }

}

Here I only rewrite the equals method, also said that if the two People object if it is equal to the name and age, is considered to be the same person.

This code is to the original wishes of the output code is "1", but in fact its output is "null". why? The reason is that while the method of rewriting equals forget rewrite hashCode methods.

While making the same logical names and ages of two objects by overriding the equals method of the object is determined to be equal (with the String class is similar), but be aware that by default, hashCode method is to store the address mapping objects. Then the output of the code is "null" is not surprising. The reason is simple, and pointed objects p1

System.out.println (hashMap.get (new People ( "Jack", 12))); phrase in new People ( "Jack", 12) is generated by two objects, they are certainly different memory address. Here is a concrete implementation of HashMap get method:

public V get (Object key) {

        if (key == null)

            return getForNullKey ();

        int hash = hash (key.hashCode ());

        for (Entry < K, V> e = table [indexFor (hash, table.length)];

            ! E = null;

            e = e.next) {

            Object k;

            if (e.hash == hash && ((k = e.key) == key || key.equals (k)))

                return e.value;

        }

        return null;

    }

When in operation so get hashmap, because different hashcdoe values obtained (Note that the above code is perhaps in some cases get the same hashcode value, but the probability is relatively small, because although the memory address two different objects may also be get the same hashcode value), thus resulting in a for loop does not get executed in the method, the direct return null.

So if you want to output the results of the above code is "1", is very simple, just need to override the hashCode method so that equals and hashCode methods remain logically consistent.

package com.cxh.test1;

import java.util.HashMap;

import java.util.HashSet;

import java.util.Set;

class People {

    private String name;

    private int age;

   

    public People (String name, int age) {

        this.name = name;

        this.age = age;

    }

   

    public void setAge (int age) {

        this.age = age;

    }

   

    @Override

    public int hashCode () {

        // TODO Auto-generated method stub

        return name.hashCode () * 37 + age;

    }

   

    @Override

    public boolean equals (Object obj) {

        // TODO Auto-generated method stub

        return this.name.equals (((People) obj) .name) && this.age == ((People) obj) .age;

    }

}

public class Main {

    public static void main (String [] args) {

       

        People p1 = new People ( "Jack", 12);

        System.out.println (p1.hashCode ());

           

        HashMap < People, Integer> hashMap = new HashMap < People, Integer> ();

        hashMap.put (p1, 1);

       

        System.out.println (hashMap.get (new People ( "Jack", 12)));

    }

}

In this way, then the output is set to "1" the.

The following excerpt Effective Java book:
• During program execution, as long as the methods used in the comparison operation equals the information is not modified, then this same object called multiple times, hashCode method must consistently return the same integer.
• If two objects are equal according to the equals method comparison, then calling the hashCode method must return two objects of the same integer result.
• If two objects are unequal according to the equals method comparison, the hashCode method does not necessarily have to return different integer.

For the second and third well understood, but first, a lot of time will be ignored. In "Java programming ideas" a book of P495 have the same first page Similar words:

The most important "design hashCode () when the factor is: Whenever the same object calling hashCode () should produce the same value if a hashCdoe generate value add talking about an object HashMap with put () when, while. with get () Shique had taken another hashCode value, then it can not obtain the object of. so if your hashCode method relies on the object variable data, users should watch out, because this data is changed, hashCode () method will generate a different hash code. "

Here's an example:

package com.cxh.test1;

import java.util.HashMap;

import java.util.HashSet;

import java.util.Set;

class People {

    private String name;

    private int age;

    public People (String name, int age) {

        this.name = name;

        this.age = age;

    }

   

    public void setAge (int age) {

        this.age = age;

    }

   

    @Override

    public int hashCode () {

        // TODO Auto-generated method stub

        return name.hashCode () * 37 + age;

    }

   

    @Override

    public boolean equals (Object obj) {

        // TODO Auto-generated method stub

        return this.name.equals (((People) obj) .name) && this.age == ((People) obj) .age;

    }

}

public class Main {

    public static void main (String [] args) {

       

        People p1 = new People ( "Jack", 12);

        System.out.println (p1.hashCode ());

       

        HashMap < People, Integer> hashMap = new HashMap < People, Integer> ();

        hashMap.put (p1, 1);

       

        p1.setAge (13);

       

        System.out.println (hashMap.get (p1));

    }

}

The results of this code output is "null", presumably one of the reasons we should all be clear.

Therefore, in designing hashCode method and the equals method, if the data object variable, it is best not to rely on the field equals and hashCode methods.
     
         
         
         
  More:      
 
- How to use the ftp tool to transfer files between Windows and Linux (Linux)
- HTML5 Fundamentals study notes (Programming)
- Python KNN algorithm of actual realization (Programming)
- How to install Ubuntu strategy game Wesnoth 1.12.0 (Linux)
- ORA-00824: can not set sga_target due to existing problem-solving (Database)
- SHELL script to use anti SSH brute force and vsftpd (Linux)
- Java object initialization (Programming)
- Linux shell scripts bubble sort (Programming)
- Ubuntu Server 14.04 installation Web server (Linux + Apache + MySQL + PHP) (Server)
- to install the deployment of LVS under CentOS 7.0 (Server)
- Build a Linux development environment under STC89C52RC (Linux)
- Linux compiler installation Redis (Database)
- Linux security configuration (Linux)
- Docker use Dockerfile created since the launch of the service support SSH container mirror (Server)
- Linux, C programming language library file handling and preparation of Makefile (Programming)
- systemctl Command Complete Guide (Linux)
- Appweb configuration in detail (Server)
- Solaris 10 nagios monitoring system (Linux)
- Using Linux command line and execute PHP code (Programming)
- Intel Graphics Installer 1.0.3 released, support for Ubuntu (Linux)
     
           
     
  CopyRight 2002-2020 newfreesoft.com, All Rights Reserved.