`

java RandomAccess 遍历效率

    博客分类:
  • java
阅读更多

 RandomAccess 是判断集合是否支持快速随即访问,以下是个测试用例:
(转发http://jianchen.iteye.com/blog/291047

 

JDK中推荐的是对List集合尽量要实现RandomAccess接口

如果集合类是RandomAccess的实现,则尽量用for(int i = 0; i < size; i++) 来遍历而不要用Iterator迭代器来遍历,在效率上要差一些。反过来,如果List是Sequence List,则最好用迭代器来进行迭代。


JDK中说的很清楚,在对List特别是Huge size的List的遍历算法中,要尽量来判断是属于RandomAccess(如ArrayList)还是Sequence List (如LinkedList),因为适合RandomAccess List的遍历算法,用在Sequence List上就差别很大,常用的作法就是:
    要作一个判断:
    if (list instance of RandomAccess) {
        for(int m = 0; m < list.size(); m++){}
    }else{
        Iterator iter = list.iterator();
        while(iter.hasNext()){}
    }


验证:

Java代码   收藏代码
  1. <span style="font-size: small;">/* 
  2.  * To change this template, choose Tools | Templates 
  3.  * and open the template in the editor. 
  4.  */  
  5. package testrandomaccess;  
  6.   
  7. import java.util.ArrayList;  
  8. import java.util.Iterator;  
  9. import java.util.LinkedList;  
  10. import java.util.List;  
  11. import java.util.RandomAccess;  
  12.   
  13. /** 
  14.  * 
  15.  * @author bolong 
  16.  */  
  17. public class TestRandomAccess {  
  18. // 初始化列表  
  19.   
  20.     public static void initList(List list, int n) {  
  21.         for (int i = 0; i < n; i++) {  
  22.             list.add(i);  
  23.         }  
  24.     }  
  25. //使用循环进行对列表的迭代  
  26.   
  27.     public static void traverseWithLoop(List list) {  
  28.         long starttime = 0;  
  29.         long endtime = 0;  
  30.         starttime = System.currentTimeMillis();  
  31.         for (int count = 0; count <= 1000; count++) {  
  32.             for (int i = 0; i < list.size(); i++) {  
  33.                 list.get(i);  
  34.             }  
  35.         }  
  36.         endtime = System.currentTimeMillis();  
  37.         System.out.println("使用loop迭代一共花了" + (endtime - starttime) + "ms时间");  
  38.   
  39.     }  
  40. //使用迭代器对列表进行迭代  
  41.   
  42.     public static void traverseWithIterator(List list) {  
  43.         long starttime = 0;  
  44.         long endtime = 0;  
  45.         starttime = System.currentTimeMillis();  
  46.         for (int count = 0; count <= 1000; count++) {  
  47.             for (Iterator itr = list.iterator(); itr.hasNext();) {  
  48.                 itr.next();  
  49.             }  
  50.         }  
  51.         endtime = System.currentTimeMillis();  
  52.         System.out.println("使用Iterator迭代一共花了" + (endtime - starttime) + "ms时间");  
  53.     }  
  54.   
  55.     public static void traverse(List list) {  
  56.   
  57.         long starttime = 0;  
  58.         long endtime = 0;  
  59.         if (list instanceof RandomAccess) {  
  60.             System.out.println("该list实现了RandomAccess接口");  
  61.             starttime = System.currentTimeMillis();  
  62.             for (int count = 0; count <= 1000; count++) {  
  63.                 for (int i = 0; i < list.size(); i++) {  
  64.                     list.get(i);  
  65.                 }  
  66.             }  
  67.             endtime = System.currentTimeMillis();  
  68.             System.out.println("迭代一共花了" + (endtime - starttime) + "ms时间");  
  69.         } else {  
  70.             System.out.println("该list未实现RandomAccess接口");  
  71.             starttime = System.currentTimeMillis();  
  72.             for (int count = 0; count <= 1000; count++) {  
  73.                 for (Iterator itr = list.iterator(); itr.hasNext();) {  
  74.                     itr.next();  
  75.                 }  
  76.             }  
  77.             endtime = System.currentTimeMillis();  
  78.             System.out.println("迭代一共花了" + (endtime - starttime) + "ms时间");  
  79.         }  
  80.     }  
  81.   
  82.     public static void main(String[] args) {  
  83.         ArrayList arraylist = new ArrayList();  
  84.         LinkedList linkedlist = new LinkedList();  
  85.         initList(arraylist, 1000);  
  86.         initList(linkedlist, 1000);  
  87.         traverse(arraylist);  
  88.         traverse(linkedlist);  
  89.         traverseWithIterator(arraylist);  
  90.         traverseWithLoop(arraylist);  
  91.         traverseWithIterator(linkedlist);  
  92.         traverseWithLoop(linkedlist);  
  93.     }  
  94. }  
  95. </span>  

 运行程序输出的结果为:


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


结论:

根据程序输出的结果的确证明了,arraylist等实现了RandomAccessj接口的类在进行迭代时使用loop效率更高,而linkedList那些未实现该接口的类在进行迭代时使用Iterator进行迭代效率更高.

分享到:
评论

相关推荐

    Java接口RandomAccess全面了解

    综上所述,`RandomAccess`接口是Java集合框架中优化遍历性能的关键,尤其是在处理大量数据时。开发者应当了解这个接口并合理利用,以提高代码的执行效率。对于支持`RandomAccess`的`List`,应优先考虑使用索引访问,...

    应聘Java时出现频率最多的问题

    - `ArrayList`和`Vector`实现了`RandomAccess`接口,支持快速随机访问。 - `HashSet`和`HashMap`遍历顺序不确定,而`LinkedHashSet`和`LinkedHashMap`按照插入顺序遍历。 - `TreeSet`和`TreeMap`元素按自然顺序...

    javalist数据结构-Java数据结构-------List.pdf

    ArrayList和Vector都继承自AbstractList,实现了List接口,同时也实现了RandomAccess接口,表明它们支持快速随机访问。LinkedList则直接实现了List接口,没有实现RandomAccess,因为它不支持快速随机访问。 总结...

    List实现类1

    ArrayList实现了RandomAccess接口,支持高效随机访问,通过索引直接获取元素。 - **遍历效率**:使用迭代器(Iterator或ListIterator)遍历效率较低,因为需要不断检查和修改内部指针;而通过for循环或for-each循环...

    Java 容器.pdf_电子版pdf版

    它实现了 RandomAccess 接口,因此支持随机访问。ArrayList 的默认大小为 10,添加元素时使用 ensureCapacityInternal() 方法来保证容量足够,如果不够时,需要使用 grow() 方法进行扩容,新容量的大小为 ...

    应聘Java笔试时可能出现问题

    - `ArrayList`和`Vector`都实现了RandomAccess接口,支持快速随机访问。 - 遍历HashSet和HashMap时,顺序不确定,但添加和删除速度快。LinkedHashSet和LinkedHashMap则按插入顺序遍历。 - TreeSet和TreeMap保证...

    Java.util包.docx

    而由于继承自AbstractList,ArrayList可以直接使用索引访问其元素,实现了RandomAccess接口,表明它支持高效的随机访问。 总之,Java.util.ArrayList是Java编程中非常重要的数据结构,它提供了一种动态、高效的方式...

    35个Java代码性能优化总结.pdf

    在遍历List集合时,如果List实现了RandomAccess接口,使用for循环通常会比使用迭代器更高效。 #### 16. 对象实例化优化 频繁地实例化同一个类型的新对象会增加垃圾回收的负担,可以考虑使用对象池来优化。 #### 17...

    从原码解析ArrayList

    在Collections工具类的某些算法中,例如二分查找,会根据对象是否实现RandomAccess接口来选择使用索引还是迭代器的方式进行查找,前者效率更高。这是因为ArrayList底层基于数组,可以通过索引直接访问,而LinkedList...

    Java中 shuffle 算法的使用

    这是因为非`RandomAccess`列表的随机访问效率较低,而数组操作更快。 对于实现了`RandomAccess`接口的列表(如`ArrayList`),可以直接在列表上进行操作,因为它们支持高效的随机访问。这个优化提高了性能,避免了...

    java ArrayList的使用与分析

    - **实现接口**:ArrayList 实现了 `java.util.List`、`java.util.RandomAccess` 和 `java.util.Iterator` 等接口,提供了丰富的操作方法。 - **性能考虑**:ArrayList 的操作速度通常比 LinkedList 快,因为它是...

    数据结构Array介绍和Java示例代码

    1. 数据随机访问(Random Access):由于具有固定大小和连续内存分配,可以通过索引快速查找和修改特定位置上的元素。 2. 空间效率高:无需额外空间来保存链接或指针信息。 Array的缺点包括: 1. 大小固定:因为...

    java面试题,肯定好,不好怪我!

    - **RandomAccess接口**:`ArrayList`和`Vector`都实现了这个接口,意味着它们支持快速随机访问。 - **遍历顺序**:`HashSet`和`HashMap`在遍历时顺序是不确定的,而`LinkedHashSet`和`LinkedHashMap`则按照元素的...

    java&c++概念及面试常问问题及解答

    与Java不同的是,C++的迭代器有多种类型,如input_iterator、output_iterator、forward_iterator、bidirectional_iterator和random_access_iterator,分别对应不同的操作能力。 在面试中,了解并能熟练运用这些基本...

    Java的线程安全与不安全集合.docx

    在`Collections.synchronizedList`的源码中,可以看到它会根据传入的列表是否实现了`RandomAccess`接口,选择不同的内部类进行包装。如果实现了`RandomAccess`,它会选择`SynchronizedRandomAccessList`,否则选择`...

    Java 基础数据结构分析

    其中,RandomAccess接口表明ArrayList支持高效的随机访问,而在遍历过程中如果元素数量发生改变(比如另一个线程添加或删除元素),则会抛出ConcurrentModificationException。 在ArrayList的`add()`方法中,如果...

    Collections 随机排序方法Shuffle源码说明

    if (size || list instanceof RandomAccess) { for (int i=size; i&gt;1; i--) list.set(i, list.set(random.nextInt(i), list.get(i-1))); } else { Object[] array = list.toArray(); shuffle(array, r); ...

    Java 多线程与并发(14-26)-JUC集合- CopyOnWriteArrayList详解.pdf

    - **类的继承关系**:`CopyOnWriteArrayList`继承自`AbstractList`并实现了`List`、`RandomAccess`、`Cloneable`和`Serializable`接口。其中,`RandomAccess`接口表明该集合支持高效的随机访问,`Cloneable`和`...

    java词汇解释

    在Java中,`java.util.Random`类提供了生成随机数的功能。 #### Collection 集合,是Java中一组存储和操作对象的容器类的统称。`java.util.Collection`接口定义了集合的基本行为。 #### ArrayList 数组列表,是一...

    简单了解Java字符串(操作)

    由于ArrayList实现了RandomAccess接口,这种方式效率较高。 ```java for (int i = 0; i (); i++) { value = (Integer) list.get(i); } ``` 3. 使用增强的for循环遍历,简洁且易于理解。 ```java for (Integer integ...

Global site tag (gtag.js) - Google Analytics