文章出自:听云博客

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示例。

  1. package Test;
  2.  
  3. import java.util.ArrayList;
  4. import java.util.Iterator;
  5. import java.util.List;
  6.  
  7. public class FastFailEX {
  8.  
  9. private static List<Integer> list = new ArrayList<Integer>();
  10.  
  11. public static void main(String[] args) {
  12.  
  13. //使用两个线程操作list
  14. new ThreadA().start();
  15. new ThreadB().start();
  16. }
  17. private static void print() {
  18. System.out.println("");
  19. Integer value = null;
  20. Iterator<Integer> iter = list.iterator();
  21. while(iter.hasNext()) {
  22. value = (Integer)iter.next();
  23. System.out.print(value+", ");
  24. }
  25. }
  26.  
  27. //向list添加元素
  28. private static class ThreadA extends Thread {
  29. public void run() {
  30. for(int i=0;i<10;i++){
  31. list.add(i);
  32. print();
  33. }
  34. }
  35. }
  36. //向list添加元素
  37. private static class ThreadB extends Thread {
  38. public void run() {
  39. for(int i=10;i<20;i++){
  40. list.add(i);
  41. print();
  42. }
  43. }
  44. }
  45.  
  46. }

运行结果:

结果说明:

当某一个线程遍历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;

  1. public class IteratorEnumerationEX {
  2.  
  3. public static void main(String[] args) {
  4. int val;
  5. Random r = new Random();
  6. Hashtable<Integer, Integer> table = new Hashtable<Integer, Integer>();
  7. for (int i=0; i<100000; i++) {
  8. val = r.nextInt(100);
  9. table.put(i, val);
  10. }
  11. iterateHashtable(table) ;
  12. enumHashtable(table);
  13. }
  14.  
  15. private static void iterateHashtable(Hashtable<Integer, Integer> table) {
  16. long startTime = System.currentTimeMillis();
  17. Iterator<Entry<Integer, Integer>> iter = table.entrySet().iterator();
  18. while(iter.hasNext()) {
  19. iter.next();
  20. }
  21. long endTime = System.currentTimeMillis();
  22. countTime("iterate",startTime, endTime);
  23. }
  24.  
  25. private static void enumHashtable(Hashtable<Integer, Integer> table) {
  26. long startTime = System.currentTimeMillis();
  27. Enumeration<Integer> enu = table.elements();
  28. while(enu.hasMoreElements()) {
  29. enu.nextElement();
  30. }
  31.  
  32. long endTime = System.currentTimeMillis();
  33. countTime("enum",startTime, endTime);
  34. }
  35.  
  36. private static void countTime(String type,long start, long end) {
  37. System.out.println(type+":"+(end-start)+"ms");
  38. }
  39. }

输出结果

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

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

Java Collection Framework概述的更多相关文章

  1. java collection framework

    java collection framework Map

  2. Java Collection Framework : List

    摘要: List 是 Java Collection Framework的重要成员,详细包括List接口及其全部的实现类.由于List接口继承了Collection接口,所以List拥有Collect ...

  3. Java Collection集合概述及其常用方法

    Collection集合概述 Java数组的长度是固定的,为了使程序能够方便地存储和操作数目不固定的一组数据,JDK类库提供了Java集合 与数组不同的是,集合中不能存放基本类型数据,而只能存放对象的 ...

  4. 集合框架(JCF/Java Collection Framework)

    集合的特点:1.数据的类型可以不同2.集合长度可变3.空间不固定集合也是对象,用于检索,存储以及传输对象集合框架的组成Collection接口和Map接口 Collection是Set接口和List接 ...

  5. 设计: ListView 接口,and the missing read-only interfaces in java collection framework

    Java的集合框架以其成功易用的设计征服了很多人(包括我),并且教科书式的诠释了泛型的应用方式. 我也是被 Joshua Bloch 的书引领入门,从中得益良多.我当然不会认为自己在设计上比他懂得更多 ...

  6. Java Collection Framework 备忘点

    最顶端是两个接口,集合和映射——  Collection<T>  /  Map<K, V> List 列表 保持插入顺序 ArrayList 擅长随机读 LinkedList ...

  7. Java Collections Framework知识结构目录

    The core collection interfaces are the foundation of the Java Collections Framework. The Java Collec ...

  8. (一)一起学 Java Collections Framework 源码之 概述

    . . . . . 目录 (一)一起学 Java Collections Framework 源码之 概述 JDK 中很多类 LZ 已经使用了无数次,但认认真真从源码级研究过其原理的还只占少数,虽然从 ...

  9. (二)一起学 Java Collections Framework 源码之 AbstractCollection

    . . . . . 目录 (一)一起学 Java Collections Framework 源码之 概述(未完成) (二)一起学 Java Collections Framework 源码之 Abs ...

随机推荐

  1. Javascript动画效果(三)

    Javascript动画效果(三) 前面我们已经介绍了速度动画.透明度动画.多物体运动和任意值变化,并且我们在Javascript动画效果(二)中介绍到我们封装了一个简单的插件雏形,接下来我们对前面的 ...

  2. 关于Entity Framework中的Attached报错的完美解决方案终极版

    之前发表过一篇文章题为<关于Entity Framework中的Attached报错的完美解决方案>,那篇文章确实能解决单个实体在进行更新.删除时Attached的报错,注意我这里说的单个 ...

  3. React Native版本升级的正确姿势

    基于React Native(简称:RN)的APP也发布了三个版本了,RN由于两周就会发布一版从最开始项目用的0.29到最近的0.37,做为一个开源项目来说更新真是跟坐火箭般快速,当然对于我们使用的人 ...

  4. Android客户端消息推送原理简介

    首先简单介绍一下Android消息推送的主要三种方式,如果你已经看过类似的文章,请直接忽略三种介绍.    1.使用SMS服务,即服务器端发送短信,然后手机客户端监听短信的广播,然后对数据进行一定的处 ...

  5. QTableWidget控件总结<二>

    QTableWidget是QT程序中常用的显示数据表格的空间,很类似于VC.C#中的DataGrid.说到QTableWidget,就必须讲一下它跟QTabelView的区别了.QTableWidge ...

  6. HoverTree项目添加了查看留言列表功能

    HoverTree项目添加了查看留言列表功能 页面:HoverTreeWeb项目下hvtpanel/usermessage/messagelist.aspx 添加留言页面:addmessage.asx ...

  7. Windows 7专业版安装VS2005与WinCE6.0开发环境

    近期更新了自己的小黑从XP更新到WIN7专业版,我花了两天时间验证了下列软件安装在WIN7 PRO是完全兼容的. 1:2011年最新更新的SourceInsight3.50.0066版本,这个是支持W ...

  8. NanUI for Winform 使用示例【第二集】——做一个所见即所得的Markdown编辑器

    经过了这一个多星期的调整与修复,NanUI for .NET Winform的稳定版已经发布.应广大群友的要求,现已将NanUI的全部代码开源. GitHub: https://github.com/ ...

  9. PHP程序员7小时学会Kotlin 第二小时

    Kotlin中,一切皆对象:PHP则并非一切皆对象,甚至不需要对象的存在即可完成系统功能开发,我们现在可以接触到的旧的系统都可以说明这一点. 基本数据类型 数值型 类型 位长 双精度浮点型Double ...

  10. Oracle数据库,join多表关联方式、union结果集合并

    join on :   多表关联 内连接 :与其他表连接 from 表1 t join 表2 s on t.字段1 =s.字段2 join 表3 n on n.字段3=t.字段1 或 from 表1 ...