【JAVA进化论】LV4-3:java里的Map
什么是Map结构呢?其实就是键值对啦,跟缓存差不多,存入一个
key-value,下次拿着key可以直接获取value的值:Map结构的基本使用
1
2
3 Map map = new XxxMap();
map.put("b", "bilibili"); //存入一个k-v
String value = map.get("b"); //这里就可以拿着b这个key值,直接取到value的值了
一、Map实现类关系图

二、Map提供了哪些主要方法?

三、几种Map实现类的区别
| 类名 | 底层结构 | 是否线程安全 | 是否允许null key | 说明 |
|---|---|---|---|---|
| HashMap | 1.7:数组+链表1.8:数组+链表(进化态:红黑树) | 否 | 是 | 最基本常用的一个Map的实现,但它并非线程安全,使用时需要注意并发问题。 |
| LinkedHashMap | 数组+链表(进化态:红黑树) | 否 | 是 | 继承了HashMap,基本功能仍然由HashMap掌管,只是它的key是有序的。 |
| TreeMap | 红黑树 | 否 | 否 | 它的key是有序的,且它同时实现了SortedMap接口。 |
| HashTable | 数组+链表 | 是 | 否 | 线程安全,性能较低,不建议使用的map。 |
| ConcurrentHashMap | 1.7:Segment【数组+链表】1.8:cas+数组+链表(进化态:红黑树) | 是 | 否 | 1.7:线程安全,由于其内部分段锁设计,性能相对HashTable较高。1.8:基于cas保证线程安全,同时结构与1.8的HashMap一致 |
⚜️ 我们现在的程序基于
java11进行,所以以1.8的优化为准,1.7做下了解即可,对内部数据结构感兴趣的话,可以参照源码或者一些博客进行深入理解,对于Map结构,至少要做到会用,它是java里经常用到的一种结构,主要用法参考图2的API。
四、实例
1 | public static void main(String[] args) { |
如上,证明下面三种Map实现类无法接收null作为key的参数。
1 | public static void main(String[] args) { |
上面的代码输出如下:
1 | AcFun |
1 | public static void main(String[] args) { |
我们之前说过,判断两只属性相同的猫相等的办法,就是重写其equals方法,那么代码块4里的size应该为1才对,因为我们说过,map里相同key会相互覆盖,既然重写了Cat类的equals方法,那么cat1和cat2属性相同就应该认为是相同的两个对象,那么最终第二个会覆盖掉第一个的值,最终size为1,不过可惜的是,这个程序结果是2,你可能会迷惑,在前面的集合类里这的确算是相同了,可惜Map的判定更加严格,需要Object的hashCode方法参与,所以我们除了要重写equals方法,还要重写Cat的hashCode方法:
1 | public class Cat extends Animal { |
现在再运行下代码块4,结果为1,hashCode方法又是什么?hashCode是对象产生后,对其地址的hash计算出来的一个哈希码,哈希码相同的对象不一定是同一个对象,但是哈希码不同的两个对象一定不是同一个对象(因为hash算法会冲突,不然散列表也不会存在解决哈希冲突这种问题了)。