一、HashMap的结构
数组索引方便,增删麻烦;链表增删方便,索引麻烦;而哈希表则集成了数组和链表的优点,索引和增删都方便。
哈希表是由数组+链表组成的,数组每个元素存储着链表的头结点。
元素的key哈希值取余数组长度:hash(key)%len计算出元素放在数组哪个下标中。HashMap的实现中有一个bean,
HashMapEntry,用来存储元素的key,value,next。当数组一个下标中放置多个HashMapEntry时,可以发现,其链表是
采用倒序插入法,把最后加入的元素放在最前面。
二、HashMap的同步
HashMap是非线程安全的,HashMap的同步有几个问题,
1.同是哈希表的HashTable,HashTable是线程安全的;
2.直接使用synchronized关键字;
3.Collections.synchronizedMap(Map m)方式;
4.使用ConcurrentHashMap,ConcurrentHashMap是线程安全的;
其中效率比较好的方式是使用ConcurrentHashMap,HashTable内部每次把整个结构锁起来,ConcurrentHashMap一般情况下
只锁住一个Segment,读取的时候不锁定,求size等操作时才锁住整个结构,所以效率会比HashTable高很多。
三、HashMap与SparseArray
官方推荐用SparseArray替代HashMap,因为一般情况下SparseArray无论是性能上还是速度上都比HashMap略胜一筹。SparseArray
是采用两个一维数组实现,HashMap采用数组+链表的方式实现;SparseArray不需进行auto-boxing进行原始类型自动封装,寻址采用
的二分查找,每次新增数据后SparseArray需要重新进行排序,当逆序寻址或索引比较离散时SparseArray效率可能会比HashMap差。