Two uses: 1.key, like value, set set; 2.key is different from value, map collection
Features: 1. Speed of Visit; 2. Additional space required; 3. disorder; 4. Possible collisions
Usage Scenario: 1. Cache; 2. Quick Find (Find out if the specified element exists in the collection);
Performance Analysis: If there is no collision, the time complexity of accessing elements is O (1), but in fact, there can be no collision, so we have to deal with the collision, we often solve the linked list, because there may be collisions, and after the collision need to iterate the list, so time complexity will change to O (L) , where L is the chain table length
Expansion factor/load factor: When the meaning reaches this value, the performance is not good. is a decimal, the Java language defaults to 0.75. In the process of using a hash table, you will not wait until all the addresses have been used up to enlarge, but will multiply the address to the hash length multiplied by the expansion factor of this value time zone expansion, the general expansion will be based on the original length multiplied by 2 as the new length
Code:
Package A;
/**
* Element class, for storing key and value
* @author LXM
*
*/
public class Entry {
int key;
int value;
Entry Next;
Public Entry () {
TODO auto-generated Constructor stub
}
Public Entry (int key,int value,entry next) {
Super ();
This.key=key;
This.value=value;
This.next=next;
}
}
Package A;
Import Java.awt.RenderingHints.Key;
Import Javax.xml.namespace.QName;
/**
* The implementation code of the hash list
* @author LXM
*
*/
public class HashTable {
/**
* Initialization length of default hash table
* Set a little bit so that we can clearly see the expansion
* In the actual use can be in the initialization of the time to pass the reference, you know, expansion is also very loss of performance
*/
private static final int default_intial_capacity = 4;
/**
* Expansion factor
*/
Private static final float load_factor = 0.75f;
/**
* Hash List array
*/
Private entry[] table = new Entry[default_intial_capacity];
Number of private int size=0;//hash table elements
Number of addresses used by private int use=0;//Hash list
/**
* According to Key, get the location in the hash table by hash function
* @param key
* @return
*/
private int hash (int key) {
return key%table.length;
}
/**
* Capacity Expansion
*/
private void Resize () {
int newlength=table.length*2;
entry[] oldtable = table;
Table = new Entry[newlength];
use=0;
for (int i=0;i<oldtable.length;i++) {
if (oldtable[i]!=null && oldtable[i].next!=null) {
Entry e =oldtable[i];
while (E.next!=null) {
Entry next = E.next;
Recalculate hash value, put in new address
int index = hash (next.key);
if (table[index]==null) {
use++;
Table[index]=new Entry ( -1,-1,null);
}
Entry temp = Table[index].next;
Entry newentry = new Entry (next.key,next.value,temp);
Table[index].next=newentry;
E=next;
}
}
}
}
/**
* Add/Modify
* @param key
* @param value
*/
public void put (int key,int value) {
int Index=hash (key);
if (table[index]==null) {
Table[index]=new Entry ( -1,-1, NULL);
}
Entry e =table[index];
if (e.next==null) {
No value, add to linked list, possibility of expansion, use Table property
Table[index].next=new Entry (key, value, NULL);
size++;
use++;
No value, description is an unused address, need to be judged is the need for expansion
if (use>=table.length*load_factor) {
Resize ();
}
} else{
There is a value in itself, modify the existing value
for (E=e.next;e!=null;e=e.next) {
int K=e.key;
if (K==key) {
E.value=value;
Return
}
}
Do not have the same value, add elements directly to the list
Entry Tempentry =table[index].next;
Entry newentry = new Entry (key,value,tempentry);
Table[index].next=newentry;
size++;
}
}
/**
* Delete
* @param key
*/
public void Remove (int key) {
int index = hash (key);
Entry Entry = Table[index];
Entry Preentry =table[index];
if (entry!=null && entry.next!=null) {
for (Entry=entry.next;entry!=null;preentry=entry,entry=entry.next) {
int K=entry.key;
if (K==key) {
Preentry.next=entry.next;
size--;
Return
}
}
}
}
/**
* Get
* @param key
* @return
*/
public int get (int key) {
int index = hash (key);
Entry e = Table[index];
if (e!=null && e.next!=null) {
for (E=e.next;e!=null;e=e.next) {
int K=e.key;
if (K==key) {
return e.value;
}
}
}
If not found, return-1
return-1;
}
/**
* Get the number of elements in a hash list
* @return
*/
public int size () {
return size;
}
/**
* Get the length of the hash table to see if the expansion
* @return
*/
public int GetLength () {
return table.length;
}
}
Package A;
public class Hashtabletest {
public static void Main (string[] args) {
TODO auto-generated Method Stub
HashTable HashTable = new HashTable ();
Hashtable.put (1, 10);
Hashtable.put (2, 20);
Hashtable.put (5, 50);//The element with key 1 falls to the same hash address, in fact the length is 2
System.out.println (Hashtable.getlength ());//hash table length is 4
Hashtable.put (3, 30);//The total length of 4, plus the length of the element is greater than 3, so the expansion of the
System.out.println (Hashtable.getlength ());//hash table length is 8
After the expansion, 4 elements fall to different addresses respectively.
Hashtable.put (6, 60);//Use 5 address
Hashtable.put (7, 70);//Use 6 addresses, 0.75 times times 8, and require expansion
System.out.println (Hashtable.getlength ());//hash table length is 16
}
}