手动简单实现HashMap

首先必须明确HashMap的数据结构,网上有很多解释;手动实现HashMap最主要就是表现出来数组加链表的结构,以及可用的put和get方法,体现出hash碰撞时候的数据处理即可。

//定义接口
public interface MyMap<K, V> {

	//长度(这里指的是数组的长度)
	int size();
	//是否为空
	boolean isEmpty();
	//get方法
	Object get(Object key);
	//put方法
	Object put(Object key, Object value);
	//内部接口 模仿Map.Entry
	interface Entry {
		Object getKey();

		Object getValue();
	}

}

//实现类
public class MyMapImpl<K, V> implements MyMap {

	// 默认容量
	private final int DEFAULT_CAPACITY = 16;

	// 数组存放Node容器
	Node[] table = new Node[DEFAULT_CAPACITY];

	// 长度
	private int size = 0;

	// 静态内部类
	static class Node implements Entry {
		// 属性
		int hash;
		Object key;
		Object value;
		Node next;

		// 构造器
		public Node(int hash, Object key, Object value, Node next) {
			super();
			this.hash = hash;
			this.key = key;
			this.value = value;
			this.next = next;
		}

		@Override
		public Object getKey() {
			return key;
		}

		@Override
		public Object getValue() {
			return value;
		}

	}

	@Override
	public int size() {
		return size;
	}

	@Override
	public boolean isEmpty() {
		return size == 0;
	}

	@Override
	public Object get(Object key) {
		int hash = hashcode(key);
		int indexOf = indexOf(hash, table.length);
		Node node = table[indexOf];
		while (node != null) {
			if (node.key.equals(key) && node.hash == hash) {
				return node.value;
			}
			node = node.next;
		}
		return null;
	}

	public int hashcode(Object key) {
		return key.hashCode();
	}

	//这里给出的索引计算是为了测试碰撞比如 key="1"和key="a"会出现hash碰撞
	public int indexOf(int hash, int length) {
		return hash % length;
	}

	@Override
	public Object put(Object key, Object value) {
		// 先判断数组中有没有这个值
		int hashcode = hashcode(key);
		int indexOf = indexOf(hashcode, table.length);
		Node node = table[indexOf];
		if (node == null) {
			// 则说明不存在,即往数组里面添加数据
			table[indexOf] = new Node(hashcode, key, value, null);
			++size;
		} else {
			// 在链表里面添加 已经发生碰撞了
			//第一个判断是看是否在数组中有相同的key和hash
			if (node.hash == hashcode && node.key == key || node.key.equals(key)) {
				// 此时应该新值替换旧值
				Object oldValue = node.value;
				node.value = value;
				return oldValue;
			} else {
				// 否则循环链表
				while (true) {
					if (node.next == null) {
						node.next = new Node(hashcode, key, value, null);
						break;
					}
					if (node.next.hash == hashcode && node.next.key == key || node.next.key.equals(key)) {
						break;
					}
					node = node.next;
				}
			}

		}
		//扩容
		if (size == table.length) {
			Node[] tableNew = new Node[table.length * 2];
			System.arraycopy(table, 0, tableNew, 0, table.length);
			table = tableNew;
		}
		return null;
	}
}

//测试类
public class MyMapTest {

	public static void main(String[] args) {
		MyMap<String,Object> map = new MyMapImpl<>();
		//map.put("name", "薛东");
		//map.put("age", 28);
		map.put("1", 111);
		map.put("a", 222);
		//System.out.println(map.get("name"));
		//System.out.println(map.get("age"));
		System.out.println(map.size());
		System.out.println(map.get("1"));
		System.out.println(map.get("a"));
	}
	
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

dong__xue

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值