背景
打开 JDK 源码,搜索 RandomAccess
我们可以看到,如下代码块,就是一个申明,里面空空如也,啥也没有。要是放在以前阿粉肯定会觉得这种写法肯定没什么用,但是毕竟看过二哥之前的文章,阿粉已经学到了,不会再那么年轻了。
public interface RandomAccess {
}
在介绍RandomAccess
的作用之前我们先看下集合 List
的两个基本的实现ArrayList
和LinkedList
,这两个的区别主要有下面几个
- 底层数据结构不同,
Arraylist
底层使用的是Object
数组;LinkedList
底层使用的是双向链表数据结构; - 添加删除的时间复杂度不同,上面提到因为
ArrayList
底层采用的是数组结构存储数据的,所以在插入和删除元素的时候,时间复杂度受元素位置的影响。 在执行添加方法的时候,ArrayList
会默认将元素添加到数组的最后,这种情况时间复杂度就是O(1)
。但是如果要在指定位置i
插入和删除元素的话时间复杂度就为O(n-i)
,因为底层的数组需要进行移动操作。 而LinkedList
底层采用链表存储,对于添加元素和删除元素的时间复杂度就不会受元素位置的影响,近似O(1)
,如果是要在指定位置i
插入和删除元素的话时间复杂度近似为o(n))
因为需要先遍历移动到指定位置再插入。 - 快速随机访问机制不同,
LinkedList
不支持高效的随机元素访问,而ArrayList
支持,快速随机访问就是通过元素的序号快速获取元素对象(对应于get(int index)方法。
揭秘
正是由于 ArrayList
和LinkedList
的随机访问性不同,才有了RandomAccess
空接口的存在!
看下面代码,我们创建 ArrayList
和LinkedList
两个集合,然后采用二分查找,找到指定的内容。我们顺藤摸瓜,可以发现RandomAccess
接口在Collections
类中binarySearch
方法中有使用,而且在给定的集合签名不同的时候会执行不同的查询方式,源码如下:
public class ListTest {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("string1");
list.add("string2");
list.add("string3");
int string2 = Collections.binarySearch(list, "string2");
System.out.println(string2);
LinkedList