java学习--集合框架

原文链接:http://davidisok.iteye.com/blog/2106563
虽然大部分对照原文,但是也有我自己的总结和拓展
概念
数据结构对程序设计有着深远的影响,在面向过程的C语言中,数据库结构用struct来描述,而在面向对象的编程中,数据结构是用类来描述的,并且包含有对该数据结构操作的方法。(STL库中的东东)
java里面,设计者对常用的数据结构和算法做了一些规范(接口)和实现(具体实现接口的类)。所有抽象出来的数据结构和操作(算法)统称为java集合框架。

各个接口和实现的这些接口的类的关系
这里写图片描述
如图可知:
Collection是集合框架的最基本的类
AbstractList,AbstractSet,AbstractQuee,AbstractMap
着四个是第二层的类,但都是抽象类,是不可以去实现的,只是
表明了可以实现的方法
在接下来的一层中(关于LinkedList的抽象类不做讨论,也就是表明了他需要实现的方法)
以下是这些类的本质,你在需要用到他们所表示的数据结构的时候就可以直接使用而不需要自己再去构造。
LinkedList:是双向列表,列表中的每个节点都包含了对前一个和后一个元素的引用
ArrayList:动态数组
HashSet:以哈希表的形式存放元素,插入删除速度很快。
TreeSet:可以给Set集合中的元素进行指定方式的排序。 保证元素唯一性的方式:通过比较的结果是否为0. 底层数据结构是:二叉树
PriorityQueue:名字很清晰了,优先级队列
ArrayDeque:可变大小的双端队列
HashMap:基于哈希表的map接口实现
TreeMap:基于红黑树实现的map接口

Part 1 Set
特点:
无序,不允许重复,检索元素效率低下,插入和删除效率高,插入和删除不会引起元素为之改变。(对应的类有:HashSet,TreeSet)
HashSet:以哈希表的形式存放元素,插入删除速度很快

Part2 List
特点:和数组类似,可以动态增长,查找元素效率高,插入删除元素效率低,因为会引起其他元素位置改变。(对应的类有ArrayList,LinkedList,Vector)
ArrayList:动态数组
LinkedList:链表,队列,堆栈

接口
1.Collection接口
Collections是针对集合类的一个帮助类。提供了一系列静态方法实现对各种集合的搜索、排序、线程完全化等操作。
Collection是最基本的集合接口,一个Collection代表一组Object,即Collection的元素。一些Collection允许相同的元素而另一些不行,一些能排序一些不行。
JavaSDK并不提供直接继承自Collection的类,JavaSDK提供的类都是继承自Collection的”子接口”如List和Set。
所有实现Collection接口的类必须提供两个标准的构造函数(这意味着上面的所有接口都实现了)
(1)无参数的构造函数用于创建一个空的Collection
(2)有一个Collection参数的构造函数用于创建一个新的Collection,这个新的Collection与传入的Collection有相同的元素,后一个构造函数允许用户复制一个Collection。
如何遍历Collection中的每一个元素
不论Collection的实际类型如何,他都支持一个iterator()的方法

Iterator it = collection.iterator();//获得一个迭代子
while(it.hasNext()){
Objectobj = it.next();//得到下一个元素
}

List和Set是由Collection派生来的两个接口

2.List接口
List是有序的*Collection,使用此接口能够精确地控制每个元素插入的位置,你可以就把它当作是数组来看待。允许相同的元素存在*。
除了具有Collection接口必备的iterator()方法外,List还提供一个listIterator()方法,返回一个 ListIterator接口,和标准的Iterator接口相比,ListIterator多了一些add()之类的方法,允许添加,删除,设定元素,还能向前或向后遍历。
实现List接口的常用类LinkedList,ArrayList,Vector和Stack
2.1LinkedList类
相对于List接口,提供额外的get,remove,insert方法在LinkedList的首部或尾部,这些操作使LinkedList可被用作堆栈,队列或双向队列。
LinkedList没有同步方法,如果多个线程同时访问一个List,则必须自己实现访问同步。
解决方法:创建List时构造一个同步的List
List list = Collections.synchronizedList(new LinkedList());

2.2ArrayList类
可变大小数组,它允许所有元素,包括null,没有同步。
默认扩充1.5倍,默认有10个

2.3vector类
Vector非常类似ArrayList,但是Vector是同步的。因为Vector是同步的,当一个Iterator被创建而且正在被使用,另一个线程改变了Vector的状态(例如,添加或删除了一些元素),这时调用Iterator的方法时将抛出ConcurrentModificationException,因此必须捕获该异常
http://www.cnblogs.com/dolphin0520/p/3933404.html
关于同步,写这篇文章目的是对集合框架有一个大致概念,里面高深的内容之后我会去详细看,对同步有疑问的可以参照。

2.4Stack类
继承自Vector所以应该也是同步安全的。基本上就和C++的栈一样,只不过peek()是查看对象,但不移除.

3.Set接口
实际上Set就是Collection,他与Collection有完全一样的接口,实际上Set就是Collection只是行为不同。
Set:
(1)Set不保存重复的元素。
(2)加入Set的元素必须定义equals()方法以确保对象的唯一性。
(3)Set不保证维护元素的次序。
3.1HashSet
它不允许出现重复元素;不保证元素集合中的顺序,允许null,但是也只允许出现一个
3.2TreeSet
可以实现排序等功能的集合,他在将对象元素添加到集合中时会自动按照某种比较规则将其插入到有序的对象序列中,并保证集合元素组成按照”升序”排列。
(a)对大量信息进行检索的时候,使用TreeSet更好,能保证在log(n)的时间内完成。
(b)TreeSet使用的是树形结构存储信息,每个节点都会保存一下指针对象,分别指向父节点,左分支,右分支,他的内存也因此比ArrayList占用的要更多。
(c)向TreeSet插入元素也更快,因为ArrayList的插入时间复杂度O(n),但是TreeSet的深度遍历只需要O(log(n))(普遍的都是set查询慢,插入快,list查询快,插入慢)
3.3LinkedHashSet:具有HashSet的查询速度,且内部使用链表维护元素的顺序(插入的次序)于是在使用迭代器遍历Set时,结果会按元素插入的次序显示。

4.Queue接口
窄化了对LinkedList方法的访问权限,也就是说方法中的参数类型如果是Queue时,就完全只能访问Queue接口所定义的方法了。
队列的特性我就不说了,就和数据结构上学的一样。
多线程的应用
如果你试图向一个已经满了的阻塞队列中添加一个元素或者是从一个空的阻塞队列中移除一个元素,将导致线程阻塞(自动依据情况进行阻塞),在多线程进行合作时,阻塞队列是很有用的工具,工作者线程可以定期的把中间结果存到阻塞队列中,而其他工作者线程把中间结果取出来并在将来修改他们,队列会自动平衡负载
如果第一个线程集运行的比第二个慢,则第二个线程集在等待结果时就会阻塞,如果第一个线程集运行的快,那么它将等待第二个线程集赶上来。
多线程中对于阻塞队列,如果你使用offer(添加一个元素并且返回true,添加失败就返回false),poll(移除并返回队列头部的元素),peak(返回头部元素,失败返回null)这些方法无法完成任务时,只会给出一个出错提示而不会抛出异常。
ArrayBlockingQueue,DelayQueue,PriorityBlockingQueue三种实现Queue的类

5.Map的功能方法
java.util.Map
四个实现类:
HashMap,HashTable,LinkedHashMap和TreeMap
HashMap和Hashtable的区别(貌似常考面试题,先做个标记)
主要区别:线程安全性,同步(synchronization),以及速度
http://www.importnew.com/7010.html
Map主要用于存储键值对,根据得到,因此不允许键重复,但允许值重复。
HashMap是一个最常用的Map,依据键的HashCode值存储数据,根据键值可以直接获取他的值具有很快的访问速度
只允许一条记录的键位NULL,允许多条记录的值为NULL。HashMap不支持线程的同步,即任意时刻可以有多个线程同时写HashMap;可能导致数据的不一致。
Hashtable与HashMap类似,不同的是
(1)它不允许记录的键或者值为空
(2)它支持线程的同步,即任一时刻只有一个线程能写Hashtable,因此也导致了Hashtable在写入时会比较慢。
LinkedHashMap保存了记录的插入顺序,在用Iterator便利的时候先得到的记录肯定是先插入的,在遍历的时候比HashMap慢。
TreeMap能够把它保存的记录根据键排序,默认是按升序排序,也可以指定排序的比较器,当用Iterator遍历TreeMap时,得到的记录是排过序的。

其他特征
(1)List,Set,Map将持有对象一律视为Object类别
(2)Collection,List,Set,Map都是接口,不能实例化,继承自它们的 ArrayList, Vector, HashTable, HashMap是具象class,这些才可被实例化。
(3)vector容器确切知道它所持有的对象隶属什么型别。vector不进行边界检查。

容器类和Array的区别,抉择
容器类仅能持有对象引用(指向对象的指针),而不是将对象信息copy一份至数列某位置。
一旦将对象置入容器内,便损失了该对象的类别信息。

List
在各种Lists中,最好的做法是以ArrayList作为缺省选择。
插入删除频繁时,使用LinkedList()
Vector总是比ArrayList慢,所以要尽量避免使用

Set
HashSet通常优于TreeSet(插入,查找)。只有当需要产生一个经过排序的序列,才用TreeSet。
TreeSet存在的唯一理由:能够维护其元素的排序状态。

Map
在各种Maps中HashMap用于快速查找

Array
当元素个数固定,用Array,因为Array效率是最高的。
结论:最常用的是ArrayList,HashSet,HashMap,Array。而且我们发现,用Treexxx都是排序的。

注意:
1、Collection没有get()方法来取得某个元素。只能通过iterator()遍历元素。
2、Set和Collection拥有一模一样的接口。
3、List,可以通过get()方法来一次取出一个元素。使用数字来选择一堆对象中的一个,get(0)…。(add/get)
4、一般使用ArrayList。用LinkedList构造堆栈stack、队列queue。
5、Map用 put(k,v) / get(k),还可以使用containsKey()/containsValue()来检查其中是否含有某个key/value。
HashMap会利用对象的hashCode来快速找到key。
* hashing
哈希码就是将对象的信息经过一些转变形成一个独一无二的int值,这个值存储在一个array中。
我们都知道所有存储结构中,array查找速度是最快的。所以,可以加速查找。
发生碰撞时,让array指向多个values。即,数组每个位置上又生成一个梿表。
6、Map中元素,可以将key序列、value序列单独抽取出来。但是抽取出来的类型不同
使用keySet()抽取key序列,将map中的所有keys生成一个Set。
使用values()抽取value序列,将map中的所有values生成一个Collection。
为什么一个生成Set,一个生成Collection?那是因为,key总是独一无二的,value允许重复。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值