RandomAccess接口理解

偏执的太偏执、 2021-09-15 04:38 516阅读 0赞

https://blog.csdn.net/stick2it/article/details/53469910

根据javadoc上面的的解释是:

RandomAccess 是一个标记接口,用于标明实现该接口的List支持快速随机访问,主要目的是使算法能够在随机和顺序访问的list中表现的更加高效。

我们可以简单的看下Collections下的binarySearch方法的源码:

[java] view plain copy

  1. public static
  2. int binarySearch(List<? extends Comparable<? super T>> list, T key) {
  3. if (list instanceof RandomAccess || list.size()<BINARYSEARCH_THRESHOLD)
  4. return Collections.indexedBinarySearch(list, key);
  5. else
  6. return Collections.iteratorBinarySearch(list, key);
  7. }

从源码中我们可以看到,在进行二分查找的时候,list会先判断是否是RandomAccess也即是否实现了RandomAccess接口,接着在调用想用的二分查找算法来进行,(其中: BINARYSEARCH_THRESHOLD Collections的一个常量(5000),它是二分查找的阀值。)如果实现了RandomAccess接口的List,执行indexedBinarySearch方法,否则执行 iteratorBinarySearch方法。

分别看下这两个方法的实现:

indexedBinarySearch 方法:

[java] view plain copy

  1. private static
  2. int indexedBinarySearch(List<? extends Comparable<? super T>> list, T key) {
  3. int low = 0;
  4. int high = list.size()-1;
  5. while (low <= high) {
  6. int mid = (low + high) >>> 1;
  7. Comparable<? super T> midVal = list.get(mid);
  8. int cmp = midVal.compareTo(key);
  9. if (cmp < 0)
  10. low = mid + 1;
  11. else if (cmp > 0)
  12. high = mid - 1;
  13. else
  14. return mid; // key found
  15. }
  16. return -(low + 1); // key not found
  17. }

indexedBinarySearch 方法是直接通过get来访问元素

iteratorBinarySearch方法:

[java] view plain copy

  1. private static
  2. int iteratorBinarySearch(List<? extends Comparable<? super T>> list, T key)
  3. {
  4. int low = 0;
  5. int high = list.size()-1;
  6. ListIterator<? extends Comparable<? super T>> i = list.listIterator();
  7. while (low <= high) {
  8. int mid = (low + high) >>> 1;
  9. Comparable<? super T> midVal = get(i, mid);
  10. int cmp = midVal.compareTo(key);
  11. if (cmp < 0)
  12. low = mid + 1;
  13. else if (cmp > 0)
  14. high = mid - 1;
  15. else
  16. return mid; // key found
  17. }
  18. return -(low + 1); // key not found
  19. }

iteratorBinarySearch中ListIterator来查找相应的元素

javadoc中特别指出:

It is recognized that the distinction between random and sequential access is often fuzzy. For example, some List implementations provide asymptotically linear access times if they get huge, but constant access times in practice. Such a Listimplementation should generally implement this interface. As a rule of thumb, a List implementation should implement this interface if, for typical instances of the class, this loop:

  1. for (int i=0, n=list.size(); i < n; i++)
  2. list.get(i);

runs faster than this loop:

  1. for (Iterator i=list.iterator(); i.hasNext(); )
  2. i.next();

总结:实现RandomAccess接口的的List可以通过简单的for循环来访问数据比使用iterator访问来的高效快速。

参考文档:https://docs.oracle.com/javase/7/docs/api/java/util/RandomAccess.html

发表评论

表情:
评论列表 (有 0 条评论,516人围观)

还没有评论,来说两句吧...

相关阅读

    相关 理解 PHP 接口

    事实上 PHP 接口是有目的的。 它们是合同,就像其他开发人员的指导手册一样。 然而,可能很难理解接口为何有用。 基本 接口是一个抽象类,因此您无法实例化它。相反,

    相关 接口理解

    1.1 概述 接口,是Java语言中一种引用类型,是方法的集合,如果说类的内部封装了成员变量、构造方法和成员方法,那么接口的内部主要就是封装了方法,包含抽象方法(JDK

    相关 RandomAccess接口的作用

    通过源码我们得知该RandomAccess是一个空的接口?为什么是空的接口呢?那它的作用到底是用来干嘛的呢? 又有谁实现了它呢?实现这个接口又有什么用呢? 带着问题我们先