Java集合:整体结构

  Java中集合类是Java编程中使用最频繁、最方便的类。集合类作为容器类可以存储任何类型的数据,当然也可以结合泛型存储指定的类型(不过泛型仅仅在编译期有效,运行时是会被擦除的)。集合类中存储的仅仅是对象的引用,并不存储对象本身。集合类的容量可以在运行期间进行动态扩展,并且还提供很多很方便的方法,如求集合的并集、交集等。

二、集合类结构

  Java中的集合包含多种数据结构,如链表、队列、哈希表等。从类的继承结构来说,可以分为两大类,一类是继承自Collection接口,这类集合包含List、Set和Queue等集合类。另一类是继承自Map接口,这主要包含了哈希表相关的集合类。下面我们看一下这两大类的继承结构图:

1、List、Set和Queue

Java集合:整体结构

图中的绿色的虚线代表实现,绿色实线代表接口之间的继承,蓝色实线代表类之间的继承。

   (1)List:我们用的比较多List包括ArrayList和LinkedList,这两者的区别也很明显,从其名称上就可以看出。ArrayList的底层的通过数组实现,所以其随机访问的速度比较快,但是对于需要频繁的增删的情况,效率就比较低了。而对于LinkedList,底层通过链表来实现,所以增删操作比较容易完成,但是对于随机访问的效率比较低。

我们先看下两者的插入效率:

package com.paddx.test.collection;

import java.util.ArrayList;
import java.util.LinkedList;

public class ListTest {
    public static void main(String[] args) {
        for(int i=0;i<10000;i++){

}
        long start = System.currentTimeMillis();

LinkedList<Integer> linkedList = new LinkedList<Integer>();
        for(int i=0;i<100000;i++){
            linkedList.add(0,i);
        }

long end = System.currentTimeMillis();
        System.out.println(end - start);

ArrayList<Integer> arrayList = new ArrayList<Integer>();
        for(int i=0;i<100000;i++){
            arrayList.add(0,i);
        }

System.out.println(System.currentTimeMillis() - end);
    }
}

下面是本地执行的结果:

23

1227

  可以看出,在这种情况下,LinkedList的插入效率远远高于ArrayList,当然这是一种比较极端的情况。我们再来比较一下两者随机访问的效率:

package com.paddx.test.collection;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Random;

public class ListTest {
    public static void main(String[] args) {

Random random = new Random();

for(int i=0;i<10000;i++){

}
        LinkedList<Integer> linkedList = new LinkedList<Integer>();
        for(int i=0;i<100000;i++){
            linkedList.add(i);
        }

ArrayList<Integer> arrayList = new ArrayList<Integer>();
        for(int i=0;i<100000;i++){
            arrayList.add(i);
        }

long start = System.currentTimeMillis();


        for(int i=0;i<100000;i++){
            int j = random.nextInt(i+1);
            int k = linkedList.get(j);
        }

long end = System.currentTimeMillis();
        System.out.println(end - start);

for(int i=0;i<100000;i++){
            int j = random.nextInt(i+1);
            int k = arrayList.get(j);
        }

System.out.println(System.currentTimeMillis() - end);
    }
}

下面是我本机执行的结果:
5277
6

  很明显可以看出,ArrayList的随机访问效率比LinkedList高出好几个数量级。通过这两段代码,我们应该能够比较清楚的知道LinkedList和ArrayList的区别和适应的场景。至于Vector,它是ArrayList的线程安全版本,而Stack则对应栈数据结构,这两者用的比较少,这里就不举例了。

  (2)Queue:一般可以直接使用LinkedList完成,从上述类图也可以看出,LinkedList继承自Deque,所以LinkedList具有双端队列的功能。PriorityQueue的特点是为每个元素提供一个优先级,优先级高的元素会优先出队列。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/61db46d5dfa58d378442a98e9e1e1018.html