RandomAccess接口详解

来源:互联网 发布:veket linux安卓版 编辑:程序博客网 时间:2024/06/11 20:27

RandomAccess接口详解

Interface RandomAccess

All Known Implementing Classes:

ArrayList, AttributeList, CopyOnWriteArrayList, RoleList, RoleUnresolvedList, Stack, Vector

public interface RandomAccessMarker interface used by List implementations to indicate that they support fast (generally constant time) random access. The primary purpose of this interface is to allow generic algorithms to alter their behavior to provide good performance when applied to either random or sequential access lists.
The best algorithms for manipulating random access lists (such as ArrayList) can produce quadratic behavior when applied to sequential access lists (such as LinkedList). Generic list algorithms are encouraged to check whether the given list is an instanceof this interface before applying an algorithm that would provide poor performance if it were applied to a sequential access list, and to alter their behavior if necessary to guarantee acceptable performance.

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 List implementation 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:

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

runs faster than this loop:

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

This interface is a member of the Java Collections Framework.

Since:
1.4

以上都是从java api中截取出来的英文解释,接下来,我对此进行简要的解释。

  1. 接口存在的目的:翻开源码,你可以发现,这是一个空接口。javaapi中是有很多空接口的,如clone接口,它没有实际上的代码上的功能。只有一个标记的功能。

    那么这个RandomAccess标记是干嘛呢?

    根据api的英文解释,这个标记是用来表明,这个类是支持快速随机访问的。

  2. 在对列表进行访问的时候,可以有随机访问和连续访问(之后会用代码进行演示),自然,这两种访问方式是有效率上的区别的,对一个支持随机访问的列表应该要使用一个随机访问算法,反而言之,一个适用于连续访问的列表就应该用连续访问的算法。那么问题来了,你怎么知道要被遍历的列表到底是支持那种访问的?这个接口就是为了区分这个点。

    源码里面经常干这种事情

    if (list instance of RandomAccess) {
            for(int m = 0; m < list.size(); m++){}
        }else{
            Iterator iter = list.iterator();
            while(iter.hasNext()){}
        }

    这样一来就可以通过list实现的接口进行判断,并且执行符合其遍历模式的算法。

  3. 结论:arraylist等实现了RandomAccessj接口的类在进行迭代时使用loop效率更高,而linkedList那些未实现该接口的类在进行迭代时使用Iterator进行迭代效率更高.

  4. 测试代码(参考的这位大大的文章的代码)

    http://blog.csdn.net/keda8997110/article/details/8635005


* To change this template, choose Tools | Templates 
 * and open the template in the editor. 
 */  
package testrandomaccess;  
  
import java.util.ArrayList;  
import java.util.Iterator;  
import java.util.LinkedList;  
import java.util.List;  
import java.util.RandomAccess;  
  
/** 
 * 
 * @author bolong 
 */  
public class TestRandomAccess {  
// 初始化列表  
  
    public static void initList(List list, int n) {  
        for (int i = 0; i < n; i++) {  
            list.add(i);  
        }  
    }  
//使用循环进行对列表的迭代  
  
    public static void traverseWithLoop(List list) {  
        long starttime = 0;  
        long endtime = 0;  
        starttime = System.currentTimeMillis();  
        for (int count = 0; count <= 1000; count++) {  
            for (int i = 0; i < list.size(); i++) {  
                list.get(i);  
            }  
        }  
        endtime = System.currentTimeMillis();  
        System.out.println("使用loop迭代一共花了" + (endtime - starttime) + "ms时间");  
  
    }  
//使用迭代器对列表进行迭代  
  
    public static void traverseWithIterator(List list) {  
        long starttime = 0;  
        long endtime = 0;  
        starttime = System.currentTimeMillis();  
        for (int count = 0; count <= 1000; count++) {  
            for (Iterator itr = list.iterator(); itr.hasNext();) {  
                itr.next();  
            }  
        }  
        endtime = System.currentTimeMillis();  
        System.out.println("使用Iterator迭代一共花了" + (endtime - starttime) + "ms时间");  
    }  
  
    public static void traverse(List list) {  
  
        long starttime = 0;  
        long endtime = 0;  
        if (list instanceof RandomAccess) {  
            System.out.println("该list实现了RandomAccess接口");  
            starttime = System.currentTimeMillis();  
            for (int count = 0; count <= 1000; count++) {  
                for (int i = 0; i < list.size(); i++) {  
                    list.get(i);  
                }  
            }  
            endtime = System.currentTimeMillis();  
            System.out.println("迭代一共花了" + (endtime - starttime) + "ms时间");  
        } else {  
            System.out.println("该list未实现RandomAccess接口");  
            starttime = System.currentTimeMillis();  
            for (int count = 0; count <= 1000; count++) {  
                for (Iterator itr = list.iterator(); itr.hasNext();) {  
                    itr.next();  
                }  
            }  
            endtime = System.currentTimeMillis();  
            System.out.println("迭代一共花了" + (endtime - starttime) + "ms时间");  
        }  
    }  
  
    public static void main(String[] args) {  
        ArrayList arraylist = new ArrayList();  
        LinkedList linkedlist = new LinkedList();  
        initList(arraylist, 1000);  
        initList(linkedlist, 1000);  
        traverse(arraylist);  
        traverse(linkedlist);  
        traverseWithIterator(arraylist);  
        traverseWithLoop(arraylist);  
        traverseWithIterator(linkedlist);  
        traverseWithLoop(linkedlist);  
    }  

 运行程序输出的结果为:

该list实现了RandomAccess接口
迭代一共花了47ms时间
该list未实现RandomAccess接口
迭代一共花了15ms时间
使用Iterator迭代一共花了79ms时间
使用loop迭代一共花了46ms时间
使用Iterator迭代一共花了47ms时间
使用loop迭代一共花了797ms时间

原创粉丝点击