源码分析之手写1.7HahMap(三)

public interface ExtMap<K, V> {

	// 向集合中插入数据
	public V put(K k, V v);

	// 根据k 从Map集合中查询元素
	public V get(K k);

	// 获取集合元素个数
	public int size();

	interface Entry<K, V> {
		K getKey();

		V getValue();

		V setValue(V value);
	}

import com.mayikt.jdk7hash.ExtMap.Entry;

/**
 * 手写jdk1.7的hashMap
 * 
 * @author zjmiec
 *
 */
public class ExtJdk7HaspMap<K, V> implements ExtMap<K, V> {

	// 1.定义table 存放HashMap 数组元素 默认不初始化容器 拦截在
	Node<K, V>[] table = null;
	// 2.实际用到table 存储容量大小
	int size;
	/**
	 * 3.默认负载因子 0.75 扩容用到,负载因子越小。hash冲突几率越低, 根据每个链表个数
	 */
	float DEFAULT_LOAD_FACTOR = 0.75f;
	// 4.table 默认初始大小 16
	int DEFAULT_INITIAL_CAPACITY = 16;

	public V put(K k, V v) {
		// 1.判断table数组大小是否为空(如果为空,做初始化操作)
		if (table == null) {
			table = new Node[DEFAULT_INITIAL_CAPACITY];
		}
		/**
		 * 2.判断数组 是否需要扩容 为什么需要扩容? 使用链表查询,链表越长,查询效率越慢,而且, 数组存储采用hash下标,
		 * 过短会导致hash冲突的几率增加 如果size大于12,进行扩容数组,大小为之前的两倍
		 */
		if (size > DEFAULT_LOAD_FACTOR * DEFAULT_INITIAL_CAPACITY) {
			// 开始对数组扩容

		}
		// 3.计算hash制定下标
		int index = getIndex(k, DEFAULT_INITIAL_CAPACITY);
		Node<K, V> node = table[index];
		if (node == null) {
			// 没有hash冲突
			node = new Node<K, V>(k, v, null);
			size++;
			// return node.setValue(v);
		} else {
			Node<K, V> newNode = node;
			// 發生hash冲突key 直接添加(冲突node)到前面了,不是往后加
			while (newNode != null) {
				if (newNode.getKey().equals(k) || newNode.getKey() == k) {
					// hash相同,而且equals相同 说明是同一个对象,进行修改值
					// node.value=v;
					return newNode.setValue(v);
				} else {
					// 继续添加 排在前面hashCode 取模余数相同存
					if (newNode.next == null) {
						// 遍历node到最后没有存在相同的key,就会添加node
						node = new Node<K, V>(k, v, node);
						size++;
					}
				}
				newNode = newNode.next;
			}

		}
		table[index] = node;
		return null;
	}

	private void resize() {
		// 1.生成新的table,长度为之前的两倍
		Node<K, V>[] newTable = new Node[DEFAULT_INITIAL_CAPACITY << 1];
		// 2.重新计算index的索引,存放到新的table容器
		for (int i = 0; i < table.length; i++) {
			Node<K, V> oldNode = table[i];
			while (oldNode != null) {
				table[i] = null;// 垃圾回收
				// 获取之前的key
				K oldkey = oldNode.key;
				// 重新计算index
				int index = getIndex(oldkey, newTable.length);
				// 存放在之前的table 原来的node next
				ExtJdk7HaspMap<K, V>.Node<K, V> next = oldNode.next;
				// 如果index在newTablez发生冲突,以链表方式存储
				// 原来链表存放的是A,B,C,新链表会存储为C,B,A
				// 原来node存放新node的下一个节点
				oldNode.next = newTable[index];
				// 将之前的node赋值给newTable[index]
				newTable[index] = oldNode;
				//
				oldNode = next;
			}
		}
		// 3.将新的table的赋值给旧的table
		table = newTable;
		DEFAULT_INITIAL_CAPACITY = newTable.length;
		newTable = null;
	}

	void print() {
		System.out.println("-------" + table.length);
		for (int i = 0; i < table.length; i++) {
			Node<K, V> node = table[i];
			System.out.print("下标位置:" + i);
			while (node != null) {
				System.out.print("[ key:" + node.getKey() + ",value:" + node.getValue() + "]");
				node = node.next;

				/*
				 * if(node.next!=null){ node=node.next; }else{ node=null; }
				 */
			}
			System.out.println();
		}
	}

	public V get(K k) {
		int index = getIndex(k, DEFAULT_INITIAL_CAPACITY);
		Node<K, V> node = getNode(table[getIndex(k, DEFAULT_INITIAL_CAPACITY)], k);
		return node == null ? null : node.value;
	}

	public Node<K, V> getNode(Node<K, V> node, K k) {
		while (node.next != null) {
			if (node.getKey().equals(k)) {
				return node;
			}
			node = node.next;
		}
		return null;
	}

	public int size() {
		// TODO Auto-generated method stub
		return 0;
	}

	public int getIndex(K k, int length) {
		int hashCode = k.hashCode();
		int hash = hashCode % table.length;
		return hash;
	}

	class Node<K, V> implements Entry<K, V> {

		// 存放Map 集合key
		private K key;
		// 存放map 集合value
		private V value;

		private Node<K, V> next;

		public K getKey() {

			return this.key;
		}

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

		public V getValue() {
			// TODO Auto-generated method stub
			return this.value;
		}

		public V setValue(V value) {
			// 设置新值 返回老值
			V oldValue = this.value;
			this.value = value;
			return oldValue;
		}

	}

}

猜你喜欢

转载自blog.csdn.net/qq_41988225/article/details/84847427