In-depth research on containers-hash and hash code (2)

Source: Internet
Author: User
Tags cairo

In-depth research on containers-hash and hash code (2)
Hash for speed:

SlowMap. java indicates that creating a new Map is not difficult. But as its name SlowMap shows, it will not be very fast and should be abandoned if there is a better choice. The problem lies in the query of keys. Keys are not saved in any specific order. Therefore, you can only use simple linear queries, but linear queries are the slowest query method.

The value of hash lies in speed.:

Hash enables quick query. Because the bottleneck lies in the speed of the key query, one solution is to maintain the sort status of the key, and then use Collections. binarySearch () for query.

Hash goes furtherIt saves the key somewhere so that it can be quickly found. The fastest data structure for storing a group of elements is an array, so it is used to represent the key information (please note that I am talking about the key information, not the key itself ). But because the array capacity cannot be adjusted, there is a problem: we want to save the number of uncertain values in Map, but if the number of keys is limited by the array capacity, what should I do?

The answer is:The array does not save the key itself. InsteadKey objectGenerateNumber, Using it as the numberSubscript of the Group. ThisNumberYesHash codeGenerated by the hashCode () method defined in an Object that may be overwritten by your class (known as a hash function in computer science.

To solve the problem that the array is fixed, different keys may generate the same subscript. That is to say, there may be conflicts. Therefore, the size of the array is not important, and any key can always find its position in the array.

ThereforeThe process of querying a valueFirst, calculate the hash code.,Then, use the hash code to query the array.. If there is no conflict (if the number of values is fixed, it is possible), it may be a perfect hash function, but this is only a special case. Usually, the conflict is handled by external links: the array does not directly Save the value, but stores the list of values. Then, the values in the list are linearly queried using the equals () method. However,If the hash function is good, Each position of the array has only a small value. Therefore, instead of querying the entire list, you can quickly jump to a position of a prime number and only compare few elements. This is why HashMap is fast.

After understanding the principles of hash, we can implement a simple hash Map:

class MapEntry
  
    implements Map.Entry
   
     {private K key;private V value;public MapEntry(K key, V value) {this.key = key;this.value = value;}public K getKey() {return key;}public V getValue() {return value;}public V setValue(V value) {V result = this.value;this.value = value;return result;}@Overridepublic int hashCode() {return (key == null ? 0 : key.hashCode())^ (value == null ? 0 : value.hashCode());}@Overridepublic boolean equals(Object o) {if (!(o instanceof MapEntry)) {return false;}MapEntry me = (MapEntry) o;return (key == null ? me.getKey() == null : key.equals(me.getKey()))&& (value == null ? me.getValue() == null : value.equals(me.getValue()));}@Overridepublic String toString() {return key + " = " + value;}}class SimpleHashMap
    
      extends AbstractMap
     
       {static final int SIZE = 997;@SuppressWarnings("unchecked")LinkedList
      
       >[] buckets = new LinkedList[SIZE];public V put(K key, V value) {V oldValue = null;int index = Math.abs(key.hashCode()) % SIZE;if (buckets[index] == null) {buckets[index] = new LinkedList
       
        >();}LinkedList
        
         > bucket = buckets[index];MapEntry
         
           pair = new MapEntry
          
           (key, value);boolean found = false;ListIterator
           
            > it = bucket.listIterator();while (it.hasNext()) {MapEntry
            
              iPair = it.next();if (iPair.getKey().equals(key)) {oldValue = iPair.getValue();it.set(pair);found = true;break;}}if (!found) {buckets[index].add(pair);}return oldValue;}public V get(Object key) {int index = Math.abs(key.hashCode()) % SIZE;if (buckets[index] == null) {return null;}for (MapEntry
             
               iPair : buckets[index]) {if (iPair.getKey().equals(key)) {return iPair.getValue();}}return null;}@Overridepublic Set
              
               > entrySet() {Set
               
                > set = new HashSet
                
                 >();for (LinkedList
                 
                  > bucket : buckets) {if (bucket == null) {continue;}for (MapEntry
                  
                    mpair : bucket) {set.add(mpair);}}return set;}}public class Main2 {public static void main(String[] args) {{CAPE VERDE=Praia, ANGOLA=Luanda, ETHIOPIA=Addis Ababa, BENIN=Porto-Novo, CONGO=Brazzaville, LESOTHO=Maseru, CENTRAL AFRICAN REPUBLIC=Bangui, EQUATORIAL GUINEA=Malabo, ERITREA=Asmara, COMOROS=Moroni, BURKINA FASO=Ouagadougou, GABON=Libreville, THE GAMBIA=Banjul, GUINEA=Conakry, EGYPT=Cairo, BURUNDI=Bujumbura, ALGERIA=Algiers, CAMEROON=Yaounde, GHANA=Accra, KENYA=Nairobi, COTE D'IVOIR (IVORY COAST)=Yamoussoukro, BISSAU=Bissau, DJIBOUTI=Dijibouti, CHAD=N'djamena, BOTSWANA=Gaberone}[CAPE VERDE = Praia, ANGOLA = Luanda, ETHIOPIA = Addis Ababa, BENIN = Porto-Novo, CONGO = Brazzaville, LESOTHO = Maseru, CENTRAL AFRICAN REPUBLIC = Bangui, EQUATORIAL GUINEA = Malabo, ERITREA = Asmara, COMOROS = Moroni, BURKINA FASO = Ouagadougou, GABON = Libreville, THE GAMBIA = Banjul, GUINEA = Conakry, EGYPT = Cairo, BURUNDI = Bujumbura, ALGERIA = Algiers, CAMEROON = Yaounde, GHANA = Accra, KENYA = Nairobi, COTE D'IVOIR (IVORY COAST) = Yamoussoukro, BISSAU = Bissau, DJIBOUTI = Dijibouti, CHAD = N'djamena, BOTSWANA = Gaberone]SimpleHashMap
                   
                     m = new SimpleHashMap
                    
                     ();m.putAll(Countries.capitals(25));System.out.println(m);System.out.println(m.entrySet());}}
                    
                   
                  
                 
                
               
              
             
            
           
          
         
        
       
      
     
    
   
  

Because Slot)Usually called Bucket)Therefore, we name the array indicating the actual hash list as a bucket.

To make the hash distribution even, the quantity of buckets usually uses prime numbers. Note: In order to automatically handle conflicts, an array of the conflict list is used;

Each new element is directly added to a specific bucket at the end of the list. Even if Java does not allow you to create a Generic Array, you can create a reference pointing to this array. Here, it is very convenient to convert to this type of array to avoid extra transformation in the code below.

For the put method, hashCode () is called for the key and its result is forcibly converted to a positive number. To fit the size of the bucket array, the touch operator modulo the size of the array. If a position in the array is null, this indicates that no element has been hashed to this point. Therefore, to save the object that has just been hashed to the position, you need to create a secret list that loves you. The general process is to check whether there are the same elements in the list at the current position. If yes, the old value will be paid to oldValue, and then the old value will be replaced with the new value. Tag found to track whether the old key-value pair is found. If not, add the new one to the end of the list.

The get () method calculates indexes in the bucktes array in the same way as the put () method (this is important to ensure that the same location is calculated). If this location exists, queries are performed.

Note that this implementation does not mean performance optimization; it just wants to display the operations performed by the hash ing table.



Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.