java学习:java容器——Map接口(代码模拟HashMap的底层实现)

java容器——Map接口

1、概念

(1)Map提供了一种映射关系,其中的元素是以键值对(key-value)的形式存储;Map中的键值对以Entry类型的对象实例形式存在;
(2)key值不可重复,value值可以重复。一个value值可以和很多key值形成对应关系,每个key值最多只能映射到一个值。

Map接口的实现类有:HashMap、TreeMap、WeakHashMap、ConcurrentHashMap、HashTable。LinkedHashMap是HashMap的子类。

2、HashMap底层实现模拟(数组+链表)

数组+链表实现HashMap。此处模拟的是JDK1.7的HashMap实现原理。

/**
 * 自定义map实现升级版 1、提升查询效率 2、底层结构就是:数组+链表
 * 
 * @author Linlin Zhao
 * 
 */
public class map002 {
	LinkedList[] arr = new LinkedList[999];
	int size;

	public void put(Object key, Object value) {
		Entry e = new Entry(key, value);

		int a = key.hashCode() % arr.length;
		if (arr[a] == null) {
			LinkedList<Entry> list = new LinkedList<Entry>();
			arr[a] = list;
			list.add(e);
		} else {
			LinkedList<Entry> list = arr[a];
			for (int i = 0; i < list.size(); i++) {
				Entry e2 = (Entry) list.get(i);
				if (e2.key.equals(key)) {
					e2.value=value;//键重复、直接覆盖
					return;
				}
			}
			arr[a].add(e);
		}
	}

	public Object get(Object key) {
		int a = key.hashCode() % arr.length;
		if (arr[a] == null) {
			return null;
		} else {
			// 遍历list
			LinkedList<Entry> list = arr[a];
			for (int i = 0; i < list.size(); i++) {
				Entry e = (Entry) list.get(i);
				if (e.key.equals(key)) {
					return e.value;
				}
			}
		}
		return null;
	}

	public static void main(String[] args) {
		map002 map = new map002();
		map.put("001", "111");
		map.put("002", "111");
		map.put("002", "222");
		map.put("003", "333");
		System.out.println(map.get("002"));
		
	}
}
class Entry {
	Object key;
	Object value;
	public Entry(Object key, Object value) {
		super();
		this.key = key;
		this.value = value;
	}
}

3、几种Map实现类的简单对比

Map接口的实现类有:HashMap、TreeMap、WeakHashMap、ConcurrentHashMap、HashTable。LinkedHashMap是HashMap的子类。

(1)HashMap:
底层数组+链表实现,可以存储null键和null值,线程不安全。

(2)HashTable:
底层数组+链表实现,无论key还是value都不能为null,线程安全,实现线程安全的方式是在修改数据时锁住整个HashTable,效率低,ConcurrentHashMap做了相关优化。

(3)ConcurrentHashMap:
底层采用分段的数组+链表实现,线程安全。比HashTable效率更高。
通过把整个Map分为N个Segment,可以提供相同的线程安全,但是效率提升N倍,默认提升16倍。(读操作不加锁,由于HashEntry的value变量是 volatile的,也能保证读取到最新的值。)
Hashtable的synchronized是针对整张Hash表的,即每次锁住整张表让线程独占,ConcurrentHashMap只锁住了Node节点,允许多个修改操作并发进行,其关键在于使用了锁分离技术。

(4)TreeMap:
实现了SortMap接口,能够把保存的记录根据键排序,所以取出来的是排序后的键值对。
所以如果需要按自然顺序或者自定义顺序遍历键,最好使用TreeMap。

(5)LinkedHashMap:
是HashMap的子类。内部还有一个双向链表维护键值对的顺序,每个键值对既位于哈希表中,也位于双向链表中。LinkedHashMap支持两种顺序:插入顺序 、 访问顺序。
可以认为是HashMap+LinkedList,即它既使用HashMap操作数据结构,又使用LinkedList维护插入元素的先后顺序。

(6)WeakHashMap:
与HashMap类似,不同之处在于WeakMap的key值采用的是“弱引用”的方式,只要其中的key不再被外部引用,就可以被垃圾回收器回收。

相关推荐:
HashMap和HashTable的区别?

发布了57 篇原创文章 · 获赞 13 · 访问量 1124

猜你喜欢

转载自blog.csdn.net/weixin_42924812/article/details/105130451