[英]How does the List has fast random access in Java?
RandomAccess接口标识特定的java.util.List实现具有快速随机访问。 该接口试图定义一个不精确的概念:快速有多快? 该文档提供了一个简单的指南:
if repeated access using the List.get() method is faster than repeated access
using the Iterator.next() method, then the List has fast random access.
以下代码示例显示了两种访问方式:
Object o;
for (int i=0, n=list.size(); i < n; i++)
o = list.get(i);
Object o;
for (Iterator itr=list.iterator(); itr.hasNext(); )
o = itr.next();
当List.get()方法比使用Iterator.next()方法进行重复访问快时,List如何实现快速随机访问。
“快速”意味着不精确的性质是我们拥有算法复杂性(又称为“大O”符号)概念的原因。 随机访问意味着get运算的算法复杂度为O(1),对于ArrayList
是这样。 相反,对LinkedList
的get操作的算法复杂度为O(n)。
当List.get()方法比使用Iterator.next()方法进行重复访问快时,List如何实现快速随机访问。
仅建议使用list.get()的速度快于iterator.next()的情况将其标记为使用RandomAccess进行快速随机访问。 编程特定List实现的程序员仍然必须选择使其List实现RandomAccess。
可以理解,因为list.get(i)将直接查询数据,所以这样的方法调用会比iterator.next()更快(对于具有良好随机访问的List而言),因为下一个方法可能会增加其他方法的开销方法调用和其他逻辑。 如果迭代器速度更快,则可能比您可以安全地打赌,这是因为List没有良好的随机访问,并且迭代器速度更快,因为它使用了一种从节点到节点的优化方法(例如List的迭代器实现可能具有一定的访问权限)到通常是其他类专用的基础List数据)。
该示例代码确实有点误导,因为与基于迭代器的解决方案的比较有损于实际情况:
当List#get(int)方法具有恒定的渐近运行时间时,列表应实现RandomAccess接口! (用大O表示法写为O(1))。
考虑一个ArrayList
:内部存储在数组中的数据。 调用arrayList.get(1)
将花费与调用arrayList.get(100000)
相同的时间。
与此相反:一个LinkedList
不提供RandomAccess
。 虽然你仍然可以调用linkedList.get(1)
和linkedList.get(100000)
后者将需要更长的时间,因为它直到它到达第十万元素遍历整个列表。
有一种方法可以在链表上实现O(log n)(最坏的情况)随机访问。 该方法与跳过列表,冈崎的列表和Haskell的树没有任何关系。 它已经在这里提出。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.