JAVA集合框架之AbstractCollection抽象类和AbstractList抽象类

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

Vector 类 继承了 AbstractList抽象类,AbstractList又继承自AbstractCollection抽象类

AbstractCollection抽象类

部分参考自 http://blog.csdn.net/u011518120/article/details/51924587
这里写图片描述
这里写图片描述

AbstractCollection存在的意义

按照文档原话:

This class provides a skeletal implementation of the Collection
interface, to minimize the effort required to implement this interface

只有iterator()方法和size()方法没有实现,其他都已实现,逻辑也都很简单,但值得注意的是这些方法都依赖于iterator对象,比如contains(Object)方法:
这里写图片描述
又比如retainAll(取交集)
这里写图片描述

toArray()

toArray() 的方法实现值得注意
这里写图片描述

The length of the returned array is equal to the number of elements returned by the iterator, even if the size of this collection changes during iteration, as might happen if the collection permits concurrent modification during iteration.

这一套复杂的操作保证了在多线程执行toArray()方法时可能出现的读脏数据问题
这个问题就是size()的问题:
一个线程做toArray
另一个线程做iterator.remove()
remove()进行了一半的时候 另一个线程获取了size并执行toArray,即:
remove()–》释放空间
另一个线程—————–toArray() { getSize() }
remove()–》size–;

T[] toArray(T[] a)

这里写图片描述
这里我有个疑问,会走到else吗?
只有a!=r才会机会进入 else if 和else
什么时候a!=r? 函数的第二条语句就决定了:a比size小的时候,r会新建一个数组。
那么能走到else if的时候,a一定比size小

AbstractList抽象类

AbstractList抽象类继承自AbstractCollection抽象类,实现List接口
这里写图片描述
AbstractCollection是实现了Collection接口的方法
同理AbstractList实现了List接口的方法,依赖于ListIterator
这里写图片描述

subList:假的子表

大多数方法很普通,而subList方法很有趣,
我们之前想当然的认为,如果调用subList方法返回的一定是一个字表,这个字表肯定小于等于原来的表,但其实不是这样的!!!
这里写图片描述
等一下再解释这个三目运算符的意义,我们先看SubList是个什么东西?
这里写图片描述
原来如此!其实SubList中保存的list还是整个list,只是通过index和offset的各种运算,实现“看起来是一个”子列表

RandomAccessSubList

这里写图片描述
他实现了RandomAccess接口,而RandomAccess是一个标记接口,啥叫标记接口?就是接口里面什么都不定义,光杆司令!
这里写图片描述
这有啥用呢,我之前一直错误的认为,标记接口是给JVM看的,底层会实现一些特别牛B的方法,比如实现了RandomAccess标记接口,JVM就自动的可以随机访问??
看了这个以后豁然开朗http://blog.csdn.net/keda8997110/article/details/8635005

原来是给程序员看的,程序员先判断一下拿到的是不是一个“可随机访问”的东西,也就是instance of RandomAccess。如果是,那就可以做一些事情,简便原本的工作。
如Collections类的shuffle方法
这里写图片描述
另外可参考 https://www.zhihu.com/question/50909512?sort=created
“并不是说实现了这个接口,类就拥有了某种能力,而是反过来,一个类先拥有了某种能力,然后作者给它打上一个标记,声明我这个类拥有这种能力”
“这个设计是从jdk1.2时代开始的,那个时候还没有Annotation的机制,所以大量的使用了这种标记接口的模式,到后来Java引入了Annotation之后,这种标记接口的模式就用得少了,用Annotation更加自然”

猜你喜欢

转载自blog.csdn.net/u012364631/article/details/78782870
今日推荐