手写HashMap,实现put,get以及扩容

很晚了不多说了,直接贴代码,看完就会了解HashMap是如何实现数组+链表存储的,希望能给大家带来帮助,如果有疑问和纠正,请留言,第一时间回复


public class MyHashMap<K,V> {

	public Node<K,V>[] table;
	
	private static final int DEFAULT_INITAIL_CAPACITY = 1<<4;
	
	//负载因子
	private static final float DEFAULT_LOAD_FECTOR = 0.75f;
	
	//非null的个数
	private static int size;
	
	private static int theshold;
	
	static class Node<K,V>{
		
		private int hash;
		
		private K key;
		
		private V value;
		
		private Node<K,V> next;

		public Node(int hash, K key, V value, Node<K, V> next) {
			super();
			this.hash = hash;
			this.key = key;
			this.value = value;
			this.next = next;
		}

		public int getHash() {
			return hash;
		}

		public void setHash(int hash) {
			this.hash = hash;
		}

		public K getKey() {
			return key;
		}

		public void setKey(K key) {
			this.key = key;
		}

		public V getValue() {
			return value;
		}

		public void setValue(V value) {
			this.value = value;
		}

		public Node<K, V> getNext() {
			return next;
		}

		public void setNext(Node<K, V> next) {
			this.next = next;
		}

		@Override
		public String toString() {
			StringBuffer stringBuffer = new StringBuffer();
			stringBuffer.append(key+"("+hash+")");
			stringBuffer.append("=");
			stringBuffer.append(value);
			stringBuffer.append(",");
			if(null != next){
				stringBuffer.append(next.toString());
			}
			return stringBuffer.toString();
		}
	}
	
	/**
	 * 添加元素
	 * @param key
	 * @param value
	 */
	public void put(K key,V value){
		//获取hash
		int hash = Objects.hashCode(key);
		
		//指定数组长度,初始化数组
		int length = DEFAULT_INITAIL_CAPACITY;
		
		if(table == null){
			theshold = (int)(DEFAULT_INITAIL_CAPACITY * DEFAULT_LOAD_FECTOR);
			table = new Node[length];
		}
		
		//根据hashCode取模算出数组下标
//		int i = hash % length;
		// &运算代替取模
		int i = hash & (length -1);//0000-1111 0-15
		
		//判断table[i]是否存在
		if(null == table[i]){
			table[i] = new Node<K, V>(hash,key,value,null);
		}else{
			Node<K,V> node = table[i];
			//判断table[i].key是否等于传入的key
			if((node.hash == hash) && (node.key == key ||((key !=null) && node.key.equals(key)))){
				node.value = value;
			}else{
				for (int count = 0;; count++) {
					if(null == node.next){
						node.next = new Node<K, V>(hash,key,value,null);
						break;
					}
					//判断next
					if((node.next.hash ==hash) && (node.next.key == key || (key != null && node.next.key.equals(key)))){
						node.next.value = value;
						break;
					}
					node = node.next;
				}
			}
		}
		size++;
		if(size >= theshold){
			resize();
		}
	}
	
	//扩容方法
	private void resize(){
		//大小翻倍
		int newCapacity = table.length << 1;
		theshold = (int)(newCapacity * DEFAULT_LOAD_FECTOR);
		Node<K,V>[] newTable = new Node[newCapacity];
		//转移数据
		for (Node<K, V> oldNode : table) {
			if(null == oldNode){
				continue;
			}
			for (int count = 0;; count++) {
				if(oldNode == null){
					break;
				}
				Node<K,V> next = oldNode.next;
				//新table的下标
				int i = oldNode.hash & (newCapacity -1);
				
				oldNode.next = newTable[i];
				newTable[i] = oldNode;
				
				oldNode = next;
			}
		}
		//替换table
		table = newTable;
	}
	
	/**
	 * 获取元素
	 * @param key
	 * @return
	 */
	public V get(K key){
		//获取key的hash
		int hash = Objects.hashCode(key);
		//判断table
		if(table == null || table.length <= 0){
			return null;
		}
		//根据hashCode取模算出数组下标
//		int i = hash % length;
		// &运算代替取模
		int i = hash & (table.length -1);//0000-1111 0-15
		
		Node<K,V> node = table[i];
		
		if(node == null){
			return null;
		}
		
		//按断key是否相等
		if((node.hash == hash) && ((node.key == key) || (key != null && node.key.equals(key)))){
			return node.value;
		}else{
			for (int count = 0;; count++) {
				if(node.next != null){
					if((node.next.hash == hash) && ((node.next.key == key) || (key != null && node.next.key.equals(key)))){
						return node.next.value;
					}
					node = node.next;
				}
			}
		}
	}
	
	@Override
	public String toString() {
		StringBuffer stringBuffer = new StringBuffer("{");
		for (Node<K, V> node : table) {
			if( null == node){
				continue;
			}
			stringBuffer.append(node.toString());
		}
		stringBuffer.append("}");
		return stringBuffer.toString();
	}
	
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值