Collection of Java Hashtable Getting Started Series (X)

Foreword

At the time of enrollment, the school established for each of our children's shoes a file of information, of course, each file corresponds to the file number information, as well as in the school library, the library for each book are made up of a unique book number, then the problem It came when we need to quickly be found by file number corresponding to the file information or quickly found a corresponding number of books by the secretary, this time we can kind of data structure through it? The previous section, we explain in detail the ArrayList and LinkedList, ArrayList we know the bottom is the one-dimensional array, but we do not know in advance the index in the array, then querying the corresponding file number or the number of books need to loop through, this time time complexity certainly not the O (1), even though we know that if the index key index but great at this time is no longer suitable as an array index, if the query by LinkedList doubly linked list, certainly not by our analysis is O (1), this time need hash algorithm used in the acquisition of the time constant of the time complexity of O (1). We used to call it hash, actually called hash, hash is a technology from a group of similar objects uniquely identifies a particular object is used.

Hash 

In the hash, by using a hash function to convert large key small key, then stores these values ​​in a data structure called a hash table. The basic idea is the uniform distribution of hash entries (key / value pairs) in the array, each element assigned by a key lookup key (warp key) is, we have access to the corresponding elements in O (1) time. Computing a hash function to an index, the index can be found or recommendation insertion position of the element. A hash sub-step performed as follows: By using a hash function element is converted to an integer. This element can be used as indexes in the original storage element, the element belongs to the hash table. This element is stored in the hash table, the hash key can be used to quickly retrieve it.

hash = hashfunc(key)
index = hash%array_size

The most important is to obtain the above-described hash value of the key by hash function, and then the resulting hash value to the size of the array is stored in the index address that is molded in a hash table. In the method, the hash has nothing to do with the size of the array, and then by using a modulo (%) which was reduced to an index (a number between 0 and array_size - 1). To achieve good hashing mechanism, it has the following basic requirements of a good hash function is very important:

Easy to calculate: it should be easy to calculate, and can not be the algorithm itself (not for algorithm algorithm).

Uniform distribution: it should provide uniform distribution in the hash table, it should not lead to aggregation.

Fewer collisions: the different elements should be mapped to avoid conflicts when the same hash value.

Note: No matter how good hash function, conflict is inevitable, therefore, in order to maintain the performance of the hash table, it is important to resolve the conflict through a variety of techniques to manage conflict. The step of using a hash function stored objects: Create an array of size M is. Selecting a hash function, h, the object to an Integer from 0,1, ..., M-1 mapping. These objects into the array index calculated by the hash function index = h (object), such array is called a hash table . So how do we choose a hash function? One way to create a hash function is to use Java's hashCode () method. hashCode () method is implemented in Object class, so each class in Java inherit it. The hash code provides a digital representation of an object, we take a look at the following code sample:

        String obj1 = String.valueOf(4);
        String obj2 = String.valueOf(16);
        String obj3 = String.valueOf(68);
        String obj4 = String.valueOf(125);
        String obj5 = String.valueOf(255);

        System.out.println(obj1.hashCode() % 5);
        System.out.println(obj2.hashCode() % 5);
        System.out.println(obj3.hashCode() % 5);
        System.out.println(obj4.hashCode() % 5);
        System.out.println(obj5.hashCode() % 5);

As the hash array size is 5, we create a hash function is used in Java provide to us hashcode method, the image above to print out the number is the index in the hash table to store address. At this point we found obj4 and stored in obj1 address hash table, like this is what we call the conflict. Resolve conflict in hash four ways: (1) open addressing method called a linear probe or a call or closed hashing, (2) re-hashing, (3) chain address method, (4) establishing a common overflow area . Over here I give you a demonstration of two common, linear probing or addressing method known as open-chain and address method, we first look at open addressing method.

Open addressing hash conflict law

In open addressing, all entries in the records are stored in the array itself, rather than the linked list. When we insert new elements or entries, first calculate the hash value of the hash index, then check array (hash index from the beginning). If the hash index address is not occupied, the entry will be inserted at the address recorded hash index, otherwise it will proceed with a probe sequence until it finds an unoccupied address. Probe sequence is a sequence to follow when traversing entries. In various probe sequence can have different spacing between successive slots or inlet probe. When the search items, the array will be scanned in the same order, until it finds the target element or find unused address, which means there is no such table Mingha Xi table key, called "Open Addressing" refers to an element by the address is not its hash value is determined. Linear probe means fixed interval between successive probe (usually 1). Assume specific hash index is an index entry. Linear detection probe sequence will be:

index = index % hashTableSize
index = (index + 1) % hashTableSize
index = (index + 2) % hashTableSize
index = (index + 3) % hashTableSize

.......

As means indicate when the hash value of the specified key is occupied, the hash value will be incremented at intervals of 1, so once increments until you find the index unoccupied storage address, as follows:

public  class the HashTable { 

    // Array capacity 
    Private  int Capacity; 

    // hash key array 
    Private the Entry [] entries It = {}; 

    public the HashTable ( int Capacity) {
         the this .capacity = Capacity; 
        entries It = new new the Entry [ the this .capacity ]; 
    } 

    // Add pair 
    public  void PUT (String Key, String value) {
         Final the Entry hashEntry = new new the Entry (Key, value);
         int the hash = getHash (Key); 
        entries It [the hash]= hashEntry;
    }

    //获取键哈希值
    private int getHash(String key) {
        int hashCode = key.hashCode();
        int hash = hashCode % capacity;
        while (entries[hash] != null) {
            hashCode += 1;
            hash = hashCode % capacity;
        }
        return hash;
    }

    //获取指定键值
    public String get(String key) {
        int hashCode = key.hashCode();
        int hash = hashCode % capacity;
        if (entries[hash] != null) {
            while (!entries[hash].key.equals(key))
            {
                hashCode += 1;
                hash = hashCode % capacity;
            }
            return entries[hash].value;
        }
        return null;
    }

    private class Entry {
        String key;
        String value;

        public Entry(String key, String value) {
            this.key = key;
            this.value = value;
        }
    }
}

We will add in the console above the test data to our custom class hash table, then the corresponding key values ​​to query, as follows:

public class Main {

    public static void main(String[] args) {

        HashTable table = new HashTable(5);

        table.put(String.valueOf(4), String.valueOf(4));
        table.put(String.valueOf(16), String.valueOf(16));
        table.put(String.valueOf(68), String.valueOf(68));
        table.put(String.valueOf(125), String.valueOf(125));
        table.put(String.valueOf(255), String.valueOf(255));

        System.out.println(table.get(String.valueOf(4)));
        System.out.println(table.get(String.valueOf(125)));
    }
}

Hash conflict chain address law 

We do this by using a single address list chain method, the chain address law is one of the most commonly used conflict resolution techniques in a single list, each element of the hash table is a linked list in order of elements stored in the hash table, you must insert a specific list. If there is any conflict (i.e. two different elements with the same hash value), then these two elements are stored in the same linked list, the entry is scanned to find the cost of the selected list to obtain a desired key, if the key sufficiently uniform distribution, the average cost is searched only depends on the average number of keys per list. To the chain address method, the worst case is that all entries are inserted into the same list. Lookup process may have to scan all of its entries, so the worst case into the number (N) and the entries in the table of costs proportional hash table address method is a schematic presence of a chain as follows:

In the beginning of our example given, the key 16 and the hash value 125 of the same we will store it into the same linked list, then we implemented method link address codes by way of example, as follows:

public  class the HashTable { 

    // Array capacity 
    Private  int Capacity; 

    // hash key array 
    Private the Entry [] entries It = {}; 

    public the HashTable ( int Capacity) {
         the this .capacity = Capacity; 
        entries It = new new the Entry [ the this .capacity ]; 
    } 

    // Add pair 
    public  void PUT (String key, String value) {
         // Get the value of the hash key 
        int the hash = getHash (key); 

        // instantiate the class keys and values stored 
        final= HashEntry the Entry new new the Entry (Key, value); 

        // if the key in the array is placed directly conflict No 
        IF (entries It [the hash] == null ) { 
            entries It [the hash] = hashEntry; 
        } 

        // If the conflict is found hash value is stored in a single linked list for the next reference 
        the else { 
            the Entry TEMP = entries it [the hash];
             the while (temp.next =! null ) { 
                TEMP = temp.next; 
            } 
            temp.next = hashEntry; 
        } 
    } 


    // Gets the hash key values 
    Private  int getHash(String key) {
        return key.hashCode() % capacity;
    }

    //获取指定键值
    public String get(String key) {

        int hash = getHash(key);

        if(entries[hash] != null) {

            Entry temp = entries[hash];

            while( !temp.key.equals(key)
                    && temp.next != null ) {
                temp = temp.next;
            }
            return temp.value;
        }

        return null;
    }

    private class Entry {
        String key;
        String value;
        Entry next;

        public Entry(String key, String value) {
            this.key = key;
            this.value = value;
            this.next = null;
        }
    }
}

Like the console code and demo OpenAddressed law and consistent print out the results, it is not given here. Here we realized the hash algorithm and hash algorithm to solve the conflict most common techniques: open-addressable and chain address law.

to sum up

In this section we continue to understand the concept of the corresponding algorithm is analyzed in detail in the next section we Hashtable pave the way, well, this section we stop here, thank you for reading, we see the next section. 

Guess you like

Origin www.cnblogs.com/CreateMyself/p/11509691.html