Java Collection Framework概述

文章出自:听云博客

Collection概述

Java collection是java提供的工具包,包含了常用的数据结构:集合、链表、队列、栈、数组、映射等。

Java集合主要可以划分为4个部分:List列表、Set集合、Map映射、工具类(Iterator、Arrays和Collections)。

Java collection 结构图

通过上图我们可以看出

  • Collection是一个interface

Collection有List和Set两大分支。

List<E>是一个队列,根据下标索引,第一个元素的下标是0,List的实现类有LinkedList, ArrayList, Vector, Stack。List是有序的队列,List中可以有重复的值。

Set<E>是一个集合,SET中的值是唯一的,我们经常会遇到List去重的问题,把List转为SET就可以快速实现 Set的实现类有HastSet和TreeSet。HashSet。其中TreeSet是有序的。

  • Ma<K,V>是一个interface,即key-value键值对。Map中的每一个元素包含“一个key”和“key对应的value”。

AbstractMap是个抽象类,它实现了Map接口中的大部分API。而HashMap,TreeMap,WeakHashMap都是继承于AbstractMap。

  • Iterator。它是遍历集合的工具,我们经常使用Iterator迭代器来遍历集合。Collection的实现类都要实现iterator()函数,返回一个Iterator对象。
  • 抽象类AbstractCollection、AbstractList、AbstractSet、AbstractMap是抽象类,他们都实现了各自的大部分方法,我们直接继承Abstract类就可以省去重复编码相同的方法 。PS当时来面试的时候被问到这个问题竟然一下没想起来。

List简介

1、List 是一个接口,它继承于Collection的接口。它代表着有序的队列。

2、AbstractList 是一个抽象类,它继承于AbstractCollection。AbstractList实现List接口中除size()、get(int location)之外的函数。

3、AbstractSequentialList 是一个抽象类,它继承于AbstractList。AbstractSequentialList 实现了“链表中,根据index索引值操作链表的全部函数”。

4、ArrayList, LinkedList, Vector, Stack是List的4个实现类。

ArrayList 是一个数组队列。它由数组实现,实现了RandomAccess, Cloneable, java.io.Serializable接口,所以可以随便访问,克隆,序列化,随机访问效率高,随机插入、随机删除效率低。

LinkedList 是一个双向链表。它也可以被当作堆栈、队列或双端队列进行操作。LinkedList随机访问效率低,但随机插入、随机删除效率低。

Vector 是矢量队列,和ArrayList一样,它也是一个动态数组,由数组实现。但是ArrayList是非线程安全的,而Vector是线程安全的。

Stack 是栈,继承于Vector。栈的特点是:先进后出(First In Last Out)。

List和Vector不同,ArrayList中的操作不是线程安全的!所以,建议在单线程中才使用ArrayList,而在多线程中可以选择Vector或者CopyOnWriteArrayList。

List的使用

1、如果涉及到“栈”、“队列”、“链表”等操作,应该考虑用List,具体的选择哪个List,根据下面的标准来取舍。

2、对于需要快速插入,删除元素,应该使用LinkedList。

3、对于需要快速随机访问元素,应该使用ArrayList。

4、对于“单线程环境” 或者 “多线程环境,但List仅仅只会被单个线程操作”,此时应该使用非同步的类(如ArrayList)。

5、对于“多线程环境,且List可能同时被多个线程操作”,此时,应该使用同步的类(如Vector)。

Fail-Fast

fail-fast 机制是java集合(Collection)中的一种错误机制。当一个线程遍历某集合时,这个集合的值被其它线程改变,该线程就会抛出ConcurrentModificationException异常。

fail-fast示例。

package Test;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class FastFailEX {

    private static List<Integer> list = new ArrayList<Integer>();

    public static void main(String[] args) {

        //使用两个线程操作list
        new ThreadA().start();
        new ThreadB().start();
    }
     private static void print() {
        System.out.println("");
        Integer value = null;
        Iterator<Integer> iter = list.iterator();
        while(iter.hasNext()) {
            value = (Integer)iter.next();
            System.out.print(value+", ");
        }
    }

    //向list添加元素
    private static class ThreadA extends Thread {
        public void run() {
            for(int i=0;i<10;i++){
                 list.add(i);
                 print();
            }
        }
    }
    //向list添加元素
    private static class ThreadB extends Thread {
        public void run() {
            for(int i=10;i<20;i++){
                list.add(i);
               print();
            }
        }
    }

}

运行结果:

结果说明:

当某一个线程遍历list的过程中,list的内容被另外一个线程所改变了;就会抛出ConcurrentModificationException异常,产生fail-fast事件。

ConcurrentModificationException是在操作Iterator时抛出的异常。我们先看看Iterator的源码。在AbstractList.java中

通过以上代码段我们看到两点

1、执行next()时,要先判断iterator返回的对象中的modCount”和“当前的modCount”是否相等

2、如果不相等,则抛回异常

接下来我们要知道在什么情况下 modCount!= expectedModCount

我们来看ArrayList.java中的代码

我们现在知道,只要修改集合中的元素个数时,都会改变modCount的值。

添加时在决定是否扩空list前修改modCount,删除元素时直接修改

至此,我们就完全了解了fail-fast是如何产生的。

即,当多个线程对同一个集合进行操作的时候,某线程访问集合的过程中,该集合的内容被其他线程所改变(即其它线程通过add、remove、clear等方法,改变了modCount的值);这时,就会抛出ConcurrentModificationException异常,产生fail-fast事件。

解决fail-fast

使用CopyOnWriteArrayList 就不会产生fail-fast

上源码

从中,我们可以看出:

CopyOnWriteArrayList是自己实现了Iterator  为COWIterator。

ArrayList的Iterator调用next()时,会调用checkForComodification()比较expectedModCount和modCount的大小;CopyOnWriteArrayList的Iterator实现类中,没有checkForComodification(),所以不会抛出ConcurrentModificationException异常。

Map简介

Map是什么:public interface Map<K,V> { }

Map 是一个键值对(key-value)映射接口。Map映射中不能包含重复的键;每个键最多只能映射到一个值。

Map 接口提供三种collection 视图,允许以键集、值集或键-值映射关系集的形式查看某个映射的内容。

Map 映射顺序。有些实现类,可以明确保证其顺序,如 TreeMap;另一些映射实现则不保证顺序,如 HashMap 类。

Map 的实现类应该提供2个“标准的”构造方法:第一个,void(无参数)构造方法,用于创建空映射;第二个,带有单个 Map 类型参数的构造方法,用于创建一个与其参数具有相同键-值映射关系的新映射。实际上,后一个构造方法允许用户复制任意映射,生成所需类的一个等价映射。尽管无法强制执行此建议(因为接口不能包含构造方法),但是 JDK 中所有通用的映射实现都遵从它。

Map体系

1、Map 是映射接口,Map中存储的内容是键值对(key-value)。

2、AbstractMap 是继承于Map的抽象类,它实现了Map中的大部分API。其它Map的实现类可以通过继承AbstractMap来减少重复编码。

3、SortedMap 是继承于Map的接口。SortedMap中的内容是排序的键值对,排序的方法是通过比较器(Comparator)。

4、NavigableMap 是继承于SortedMap的接口。相比于SortedMap,NavigableMap有一系列的导航方法;如"获取大于/等于某对象的键值对"、“获取小于/等于某对象的键值对”等等。

5、TreeMap 继承于AbstractMap,且实现了NavigableMap接口;因此,TreeMap中的内容是“有序的键值对”, 它是通过红黑树实现的。它一般用于单线程中存储有序的映射。

6、HashMap 继承于AbstractMap,没实现SortedMap或NavigableMap接口;因此,HashMap的内容是无序的键值对。

7、Hashtable继承于Dictionary(Dictionary也是键值对的接口),实现Map接口;因此,Hashtable的内容也是“键值对,是无序的”。 Hashtable是线程安全的。

8、WeakHashMap 继承于AbstractMap。它和HashMap的键类型不同,WeakHashMap的键是“弱键”, 当“弱键”被GC回收时,它对应的键值对也会被从WeakHashMap中删除。JVM提供的弱引用

Set简介

Set 是继承于Collection的接口。它是一个不允许有重复元素的集AbstractSet 是一个抽象类,它继承于AbstractCollection,AbstractCollection实现了Set中的绝大部分函数,为Set的实现类提供了便利。

HastSet 和 TreeSet 是Set的两个实现类。

HashSet中的元素是无序的。

TreeSet中的元素是有序的,不支持快速随机遍历,只能通过迭代器进行遍历。

Iterator和Enumeration

在Java集合中,我们通常都通过 “Iterator(迭代器)” 或 “Enumeration(枚举类)” 去遍历集合

Enumeration是一个接口,它的源码如下

Iterator也是一个接口,它的源码如下:

1、函数接口不同

Enumeration只有2个函数接口。通过Enumeration,我们只能读取集合的数据,而不能对数据进行修改。

Iterator只有3个函数接口。Iterator除了能读取集合的数据之外,也能数据进行删除操作。

2、Iterator支持fail-fast机制,而Enumeration不支持。

Iterator和Enumeration性能对比

package Test;

import java.util.Enumeration;

import java.util.Hashtable;

import java.util.Iterator;

import java.util.Map.Entry;

import java.util.Random;

public class IteratorEnumerationEX {

    public static void main(String[] args) {
        int val;
        Random r = new Random();
        Hashtable<Integer, Integer> table = new Hashtable<Integer, Integer>();
        for (int i=0; i<100000; i++) {
            val = r.nextInt(100);
            table.put(i, val);
        }
        iterateHashtable(table) ;
        enumHashtable(table);
    }

    private static void iterateHashtable(Hashtable<Integer, Integer> table) {
        long startTime = System.currentTimeMillis();
        Iterator<Entry<Integer, Integer>> iter = table.entrySet().iterator();
        while(iter.hasNext()) {
            iter.next();
        }
        long endTime = System.currentTimeMillis();
        countTime("iterate",startTime, endTime);
    } 

    private static void enumHashtable(Hashtable<Integer, Integer> table) {
        long startTime = System.currentTimeMillis();
        Enumeration<Integer> enu = table.elements();
        while(enu.hasMoreElements()) {
            enu.nextElement();
        }

        long endTime = System.currentTimeMillis();
        countTime("enum",startTime, endTime);
    }

    private static void countTime(String type,long start, long end) {
        System.out.println(type+":"+(end-start)+"ms");
    }
}

输出结果

因为Iterator支持fail-fast所以做操作多一些性能也相对慢一些

原文链接:http://blog.tingyun.com/web/article/detail/268

时间: 2024-11-05 13:38:44

Java Collection Framework概述的相关文章

Java Collection Framework : List

摘要: List 是 Java Collection Framework的重要成员,详细包括List接口及其全部的实现类.由于List接口继承了Collection接口,所以List拥有Collection的全部操作. 同一时候.又由于List是列表类型,所以List本身还提供了一些适合自身的方法.ArrayList 是一个动态数组.实现了数组动态扩容,随机訪问效率高:LinkedList是一个双向链表,随机插入和删除效率高,可用作队列的实现. 一. 要点 List 基础特性与框架 ArrayL

Java Collection Framework : Collection 接口

一.要点 Collection 接口 Collection 接口的默认实现:AbstractCollection Optional operations(可选方法) 二.Collection 接口 1.JDK 对 Collection 接口的描述 Collection 接口是 Collection 层次结构中的根接口.Collection 表示一组对象,这些对象也称为 collection 的元素.一些 collection(List,Queue) 允许有重复的元素,而另一些(Set)则不允许.

JavaSE入门学习33:Java集合框架概述

一集合框架 (1)集合的概念 现实生活中的集合:很多的事物凑在一起. 数学中的集合:具有共同属性的事物的总体. Java中的集合类:是一种工具类,就像是容器,储存任意数量的具有共同属性的对象. (2)集合框架的概念 有了集合的概念,什么是集合框架呢?集合框架是为表示和操作集合而规定的一种统一的标准的体系结构.任何 集合框架都包含三大块内容:对外的接口.接口的实现和对集合运算的算法. 1接口:即表示集合的抽象数据类型.接口提供了让我们对集合中所表示的内容进行单独操作的可能.接口允许 集合独立操纵其

java之集合概述

集合也称容器:从大的类别分成两类:Collection和Map,也即:单列和双列列表. java编程思想中一张图说明该体系的整体结构:其中黑色着重的类是经常使用的类. 1 Collection Collection:作为单列集合的根接口.该类集合的继承体系如下: Collection分为两大类:List和Set 1)List: 特点:有序的 collection(也称为序列):列表通常允许重复的元素.       List 接口提供了特殊的迭代器,称为 ListIterator,除了允许 Ite

【DataStructure】The description of Java Collections Framework

The Java Connections FrameWork is a group of class or method and interfacs in the java.util package. Its main purpose is to provide a unified framework for implementing common data structure. A collections is a object that contains other objects,whic

Collection FrameWork

Collection FrameWork如下: Collection ├List │├LinkedList │├ArrayList │└Vector │ └Stack └Set Map ├Hashtable ├HashMap └WeakHashMap Collection是最基本的集合接口,一个Collection代表一组Object,即Collection的元素(Elements) Map提供key到value的映射

Framework概述

Framework概述 Framework框架包含三个部分,分别为客户端.服务端和Linux驱动. 服务端: 包含两个重要的类,分别是WindowManagerService(WmS),作用是:各窗口的叠放次序,隐藏或者显示窗口,和ActivityManagerService(AmS),作用是:管理所有的应用程序中的Activity. 除此之外,服务端还包括了两个消息处理类,KeyQ类:该类为WmSd的内部类,继承于KeyInputQueue类,KeyQ对象一旦创建,就立即启动一个线程,该线程会

JAVA Collection 源码分析(一)之ArrayList

到今天为止,差不多已经工作一年了,一直在做的是javaweb开发,一直用的是ssh(sh)别人写好的框架,总感觉自己现在高不成低不就的,所以就像看看java的源码,顺便学习一下大牛的思想和架构,read and write一直是提高自己编程水平的不二法门,写博客只是记录自己的学习历程,方便回顾,写的不好的地方,请多多包含,不喜勿喷,好了废话少说,现在让我们开始我们的历程把,Let's go!!!!!!!! 想看源码无从下手,不知道有没有跟我一样感觉的人们,今天用Intellij发现了可以找出类与

Java - Collection

http://blog.csdn.net/itlwc/article/details/10148321 Java - Collection 2013-08-21 15:13 4389人阅读 评论(3) 收藏 举报  分类: JavaSE(30)  版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[+] Collection层次结构 Collection [plain] view plain copy 子接口 Set,List 集合中只能放置对象的引用,不能放置原生数据类型, 我们