JAVA class set source code analysis and Implementation -- Map

Keywords: JDK

HashMap

  • The underlying structure is hash table, which uses the way of array + linked list; the storage address of the same linked list is the same;
  • Each node of the linked list is an Entry object with four parts: hash, key, value and next
  • Add an element, not to the back of the list, but to the front of the list
  • Advantages of hash table: fast addition, fast query (storage location is obtained by calculation, not by comparison), unordered, key unique
  • Key parameters: the default main array length is: 16, the default loading factor is 0.75, the capacity of each main array expansion is twice of the original, JDK 1.8 when the length of the list is greater than 8, the list becomes a red black tree;
  • Handwritten HashMap
public class MyHashMap {
	//Initialization main array size is 16
	private final int DEFAULT_INITIAL_CAPACITY = 16;
	//Define size, number of key value pairs, number of Entry objects, number of nodes
	int size;
	//Defining an Entry object array reference
	Entry[] table;
	//structure
	public MyHashMap() {
		//Initialize the main array. You can see that the default size of map is 16
		table = new Entry[DEFAULT_INITIAL_CAPACITY];
	}
	//toString method
	public String toString() {
		//Create buffer
		StringBuilder sb = new StringBuilder("{");
		//Traversal large array
		for(int i = 0; i < table.length; i++) {
			if(table[i] != null) {  //Can not be empty
				//Get the first node of the current index
				Entry e = table[i];
				while(e != null) {//Ergodic deposit
					sb.append(e.getKey() + " = " + e.getValue() + ",");
					e = e.next;
				}
			}
		}
		if(size != 0) { //Number of elements cannot be 0
				//Divide the last character
			sb.deleteCharAt(sb.length() - 1);
		}
		sb.append("}");
		//Return to String
		return sb.toString();
	}
	//size() method
	public int size() {
		return this.size;
	}
	//isEmpty() method
	public boolean isEmpty() {
		rteurn this.size == 0;
	}
	public Object get(Object key) {
		//DP Hash 
		int hash = key.hashCode();
		//Calculate storage location
		int index = hash % table.length;
		//Find value
		Entry entry = null;
		if(table[index] != null) {
			Entry e = table[index];
			while(e != null) {
				if(entry.getKey().equals(key) && entry.hash == hash) {
					entry = e;
					break;
				}	
				e = e.next;
			}
		}
		return entry == null ? null : entry.value;
	}
	//Adding method
	public void put(Object key, Object value) {
		//DP Hash 
		int hash = key.hashCode();
		//Calculate storage location
		int index = hash % table.length;
		//Store to specified location
		if(table[index] == null ) {   //If the text position is empty
			//	Direct new, put the first one
			table = new Entry(hash, key, value, null);
		}else {//If the location has elements
			//Get your head first.
			Entry entry = table[index];
			while(entry != null) {   //ergodic
				//Judge whether the key is the same
				if(entry.getKey().equals(key) && hash == entry.hash) {
					//Same as original value
					entry.value = value;
					return;
				}
				//Move downward
				entry = entry.next;
			}
			//It's not found. It's creating a plug-in to the first location
			Entry first = table[index];
			table[index]= new Entry(hash, key, value, first);
		}
		//size++
		size++;
	}
	//Node object
	static class Entry {
		//Hash value of the first key
		int hash;
		//key
		Object key;
		//value
		Object value;
		//Next node
		Entry next;
		//Structure giving value
		Entry(int hash, Object key, Object value, Entry next) {
			this.hash = hash;
			this.key = key;
			this.value = value;
			this.next = next;
		}
		//get method 
		public Object  getKey() {
			return this.key;
		}
		public Object getValue() {
			return this.value;
		}
	} 
}

Posted by acabrera on Sun, 03 Nov 2019 08:16:03 -0800