Java基础系列(四十七):集合之AbstractMap

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/vi_young_95/article/details/84448835

AbstractMap

AbstractMapAbstractListAbstractCollection等抽象类类似,它实现了Map接口的部分方法,提供了一些基础的实现,我们耳熟能详的HashMap, TreeMap, ConcurrentHashMap 都是他的子类。

构造


AbstractMap提供了一个protected修饰的无参构造方法,意味着只有它的子类才能访问(当然它本身就是一个抽象类,其他类也不能直接对其实例化),也就是说只有它的子类才能调用这个无参的构造方法。

源码分析


可以看出AbstractMap提供了一些基础方法的实现,用于到增加/修改元素的put()putAll(),用于删除元素的remove()clear(),以及其他的一些用于判断或者获取这个Map的属性的一些方法。其中需要注意的是,put()putAll()子类必须重写,因为这里的实现仅仅是抛出一个异常,如果子类不进行重写,调用该方法就会抛出一个异常。


通过源码我们不难看出,这个类的方法基本是都是通过Entry这个对象来完成的,而获取这个对象的方法是entrySet()

这里的entrySet()方法却是一个抽象方法,具体的实现需要子类来完成,这是很典型的设计模式中的模板方法模式,那么何为模板方法模式呢?其实很好理解,就是在一个方法中定义一个算法的骨架,而将一些步骤的实现延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中某些步骤的具体实现。这里因为entrySet()AbstractMap中并未实现,而是交给了它的子类去完成,但是对于该类中的方法却可以对它进行一个“算法骨架” 实现,这就是模板方法模式。

还有两个我们经常会用到的视图属性

这两个视图分别是用于键构成的集合keySet以及值构成的集合values,在JDK 8 中将volatile的关键字给去掉了,不知道为毛,有知道的朋友可以私信我,我给添上~
下面来看看怎么获取这两个视图:

可以看出,实际上它的实现是通过一个AbstractSet的匿名内部类,而该内部类的迭代器实际上就是该entrySet()的迭代器(没错,是它是它,就是它,我们的英雄小哪吒~),只不过在next()的时候调用了getKey(),而其他方法的实现都是调用了AbstractMap的中的方法,而values()方法的实现也与这个差不多,大家可以自己去源码中看一下,这里就不多占篇幅去说了。

两个内部类


没错,就是这两个货SimpleEntrySimpleImmutableEntry,他们都实现了Entry接口,那么问题来了,他们为什么是两个呢,因为从这个图上看,这俩货是一样的。。其实区别就在于setValue()这个方法。

这是SimpleEntry的setValue方法
这是SimpleImmutableEntry的setValue方法
可以看出,这两个类一个是可以修改的(SimpleEntry),而另一个是不能修改(SimpleImmutableEntry)的。这就是他们的区别所在。

视图是个啥

这节课,我们频繁的提到了一个词———集合视图,集合视图是什么?
简单的来说,就是有一定限制(只读,同步,受查,只能删除不能增加等等)的集合类,被限制的是视图,而不是集合,比如*.subList()Map.keySet()Map.values()Map.entrySet()Arrays.asList()这些都是集合视图,其实就是对原集合的一层包装 ,不同的集合视图有不同的用途,有的是只读有的是同步的。针对视图的操作会影响到集合的数据。

原创文章,文笔有限,才疏学浅,文中若有不正之处,万望告知。


公众号

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/vi_young_95/article/details/84448835