java学习笔记:集合

=====================================

java集合框架概述
集合(collection)有时也称为容器(container),是一个对象的持有者,使你能够通过有用的方法对对象进行存储和组织,以便进行更有效的访问。同大多数的编程环境一样,java平台也提供了一套集合框架,主要由一组用来操作对象的接口组成。不同接口描述一组不同数据类型。以下是简化后的集合框架:

Collection
├List
│├LinkedList
│├ArrayList
│└Vector
│ └Stack
└Set
Map
├Hashtable
├HashMap
└WeakHashMap

简单说明:

Collection:集合的根接口。提供诸如add、remove、size、toArray和(重要的)iterator等方法。

List: 接口,继承自 Collection,允许重复,以元素安插的次序来放置元素,不会重新排列。

Set:接口,继承自 Collection,不允许元素的重复,元素的存储没有任何特定的顺序,其使用自己内部的一个排列机制。

Map:接口,是一组成对的键-值对象,即所持有的是key-value pairs。Map中不能有重复的key。拥有自己的内部排列机制。

=====================================

Collection接口简介
大多数集合类型都是Collection接口的子类型,唯一例外的就是Map的子类型。Collection接口主要有如下方法:

(1) 单元素添加、删除操作:

boolean add(Object o):将对象添加给集合

boolean remove(Object o): 如果集合中有与o相匹配的对象,则删除对象o

(2) 查询操作:

int size() :返回当前集合中元素的数量

boolean isEmpty() :判断集合中是否有任何元素

boolean contains(Object o) :查找集合中是否含有对象o

Iterator iterator() :返回一个迭代器,用来访问集合中的各个元素

(3) 组操作 :作用于元素组或整个集合

boolean containsAll(Collection c): 查找集合中是否含有集合c 中所有元素

boolean addAll(Collection c) : 将集合c 中所有元素添加给该集合

void clear(): 删除集合中所有元素

void removeAll(Collection c) : 从集合中删除集合c 中的所有元素

void retainAll(Collection c) : 从集合中删除集合c 中不包含的元素

(4) Collection转换为Object数组 :

Object[] toArray() :返回一个内含集合所有元素的array

Object[] toArray(Object[] a) :返回一个内含集合所有元素的array。运行期返回的array和参数a的型别相同,需要转换为正确型别。

此外,您还可以把集合转换成其它任何其它的对象数组。但是,您不能直接把集合转换成基本数据类型的数组,因为集合必须持有对象。

“斜体接口方法是可选的。因为一个接口实现必须实现所有接口方法,调用程序就需要一种途径来知道一个可选的方法是不是不受支持。如果调用一种可选方法时,一个 UnsupportedOperationException 被抛出,则操作失败,因为方法不受支持。此异常类继承 RuntimeException 类,避免了将所有集合操作放入 try-catch 块。”

Collection不提供get()方法。如果要遍历Collectin中的元素,就必须用Iterator。

=====================================

List接口的使用

List是有序的Collection,使用此接口能够精确的控制每个元素插入的位置。用户能够使用索引(元素在List中的位置,类似于数组下标)来访问List中的元素,这类似于Java的数组。
和下面要提到的Set不同,List允许有相同的元素。

除了具有Collection接口必备的iterator()方法外,List还提供一个listIterator()方法,返回一个ListIterator接口,和标准的Iterator接口相比,ListIterator多了一些add()之类的方法,允许添加,删除,设定元素,还能向前或向后遍历。

实现List接口的常用类有LinkedList,ArrayList,Vector和Stack。

(1)
面向位置的操作包括插入某个元素或 Collection 的功能,还包括获取、除去或更改元素的功能。在 List 中搜索元素可以从列表的头部或尾部开始,如果找到元素,还将报告元素所在的位置 :

void add(int index, Object element): 在指定位置index上添加元素element

boolean addAll(int index, Collection c): 将集合c的所有元素添加到指定位置index

Object get(int index): 返回List中指定位置的元素

int indexOf(Object o): 返回第一个出现元素o的位置,否则返回-1

int lastIndexOf(Object o) :返回最后一个出现元素o的位置,否则返回-1

Object remove(int index) :删除指定位置上的元素

Object set(int index, Object element) :用元素element取代位置index上的元素,并且返回旧的元素

(2)
List 接口不但以位置序列迭代的遍历整个列表,还能处理集合的子集:

ListIterator listIterator() : 返回一个列表迭代器,用来访问列表中的元素

ListIterator listIterator(int index) : 返回一个列表迭代器,用来从指定位置index开始访问列表中的元素

List subList(int fromIndex, int toIndex) :返回从指定位置fromIndex(包含)到toIndex(不包含)范围中各个元素的列表视图

“对子列表的更改(如 add()、remove() 和 set() 调用)对底层 List 也有影响。”

=====================================

ArrayList与LinkedList

在“集合框架”中有两种常规的 List 实现:ArrayList 和 LinkedList。这两个集合类的实例可以用来存储一系列的对象引用(references),这两者的主要区别如下:

(1)ArrayList是实现了基于动态数组的数据结构,LinkedList实现了基于链表的数据结构;

(2)对于随机访问get和set,ArrayList优于LinkedList,因为LinkedList要移动指针;

(3)对于新增和删除操作add和remove,LinedList优于ArrayList,因为ArrayList要移动数据。

使用两种 List 实现的哪一种取决于我们的需求。如果需要支持随机访问,而不必在除尾部的任何位置插入或除去元素,那么,使用 ArrayList 。如果需要频繁的从列表的中间位置添加和删除元素,而只要顺序的访问列表元素,那么选择 LinkedList 。

以下有对ArrayList和LinkList的一个比较:
http://space.itpub.net/111631/viewspace-613929

LinkedList类

LinkedList类添加了一些处理列表两端元素的方法。

(1)
void addFirst(Object o): 将对象o添加到列表的开头

void addLast(Object o):将对象o添加到列表的结尾

(2)
Object getFirst(): 返回列表开头的元素

Object getLast(): 返回列表结尾的元素

(3)
Object removeFirst(): 删除并且返回列表开头的元素

Object removeLast():删除并且返回列表结尾的元素

(4)
LinkedList(): 构建一个空的链接列表

LinkedList(Collection c): 构建一个链接列表,并且添加集合c的所有元素

“使用这些新方法,您就可以轻松的把 LinkedList 当作一个堆栈、队列或其它面向端点的数据结构。”

ArrayList类

ArrayList类封装了一个动态再分配的Object[]数组,实现了可变大小的数组。它允许所有元素,包括null。每个ArrayList实例都有一个容量(Capacity),即用于存储元素的数组的大小。当元素添加到ArrayList时,它的capacity在常量时间内自动增加。 在向一个ArrayList对象添加大量元素的程序中,可使用ensureCapacity方法增加capacity。这样可以提高插入效率。

size,isEmpty,get,set方法运行时间为常数。但是add方法开销为分摊的常数,添加n个元素需要O(n)的时间。其他的方法运行时间为线性。

和LinkedList一样,ArrayList也是非同步的(unsynchronized)。

ArrayList的API帮助文档地址:
http://gceclub.sun.com.cn/Java_Docs/html/zh_CN/api/java/util/ArrayList.html

ArrayList 的两篇篇介绍文章:
http://www.jcourse.cn/read/278
http://java.chinaitlab.com/base/796805.html

=====================================

Map接口的使用
值得注意的是Map没有继承Collection接口,Map提供key到value的映射。一个Map中不能包含相同的key,每个key只能映射一个value。Map接口提供3种集合的视图,Map的内容可以被当作一组key集合,一组value集合,或者一组key-value映射。

HashMap类
HashMap和Hashtable类似,不同之处在于HashMap是非同步的,并且允许null,即null value和null key。但是将HashMap视为Collection时(values()方法可返回Collection),其迭代子操作时间开销和HashMap的容量成比例。因此,如果迭代操作的性能相当重要的话,不要将HashMap的初始化容量设得过高,或者load factor过低。

=====================================
Set接口的使用

待总结。

=====================================
迭代
collection接口定义了一个iterator方法,它返回一个实现迭代器(iterator)接口的对象。

待总结。

=====================================

集合类中同步于异步的区别

http://hi.baidu.com/godoy/blog/item/95496488615951b50f2444f0.html

经常看到介绍 ArrayList 和HashMap是异步,Vector和HashTable是同步,这里同步是线程安全的,异步不是线程安全的,举例说明:

当创建一个Vector对象时候,

Vector ve=new Vector();
ve.add("1");

当在多线程程序中,第一个线程调用修改对象ve的时候,就为其上了锁,其他线程只有等待。

当创建一个ArrayList对象时候,

ArrayList list=new ArrayList();
list.add("1");

当在多线程程序中,第一个线程调用修改对象list的时候,没有为其上锁,其他线程访问时就会报错。

eg:list.remove("1"),然后再由其他线程访问list对象的1时就会报错。

=====================================

此条目发表在java/j2ee分类目录,贴了, , , , , , , 标签。将固定链接加入收藏夹。

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据