Java.util包的 第1部分:类集框架(Java2中引入)
Date: 2007-6-20
目录
1. 类集概述
一个collection---有时也被称作容器---是一种能够把多个元素组织在同一个单元的简单对象。Collections常用来存储,获得,操作,交互集合数据。他们可以描述生活中的同一组的事物,比如一副纸牌,一个邮件文件夹—邮件的集合,或者是电话簿—姓名和电话号码对应表的集合。
(早期的Java1.2也包含collections的概念—Vector,Hashtable,array, 但是早期版本并不包括collections framework。)
集合框架是为表示和操作集合而规定的一种统一的标准的体系结构。任何集合框架都包含三大块内容:对外的接口、接口的实现和对集合运算的算法。
l Interfaces: 接口:即表示集合的抽象数据类型。接口提供了让我们对集合中所表示的内容进行单独操作的可能
l Implementations: 实现:也就是集合框架中接口的具体实现。实际它们就是那些可复用的数据结构。
l Algorithms: 算法:在一个实现了某个集合框架中的接口的对象身上完成某种有用的计算的方法,例如查找、排序等。这些算法通常是多态的,因为相同的方法可以在同一个接口被多个类实现时有不同的表现。事实上,算法是可复用的函数。
如果你学过C++,那C++中的标准模版库(STL)你应该不陌生,它是众所周知的集合框架的绝好例子。
任何集合框架都包含三大块内容:对外的接口、接口的实现和对集合运算的算法。
2. 类集接口
2.1 Collection:
Collection接口是构造类集框架的基础。它声明所有类集都将拥有的核心方法。这些方法包括:boolean add(Object o),调用add()方法可以将对象加入类集。remove(Object o
)是将一个对象从类集中删除。contains(Object o
)可以用来判断类集中是否包含了指定的对象。isEmpty()用来判断一个类集是否为空。size()可以得到类集中元素的个数。Object[]
toArray()返回一个数组,这个数组包含了类集中的元素,它为类集与数组之间提供了一条通路,可以充分利用这两者的优点。equals(Object o
)用来比较两个类集是否相等。iterator
i
terator ()对该类集返回一个迭代程序。(….?)
2.2 List:
List扩展了Collection接口,并且使用了基于零的下标。List中的元素可能通过下标来进行插入与访问。Void add(int index, Object o)。 int indexOf(Object obj)。
int lastIndexOf(Object o), Object remove(int index)删除指定下标的元素,删除后,列表会被压缩。Object get(int index), Object set(int index, Object obj)返回指定下标的元素值或赋值。
2.3 Set:
Set也扩展Collection, 而与List不同的是,Set中的对象元素不能重复,也就是说你不能把同样的东西 两次放入同一个Set容器中。它没有自己的特定的方法。
2.4 StoredSet:
StoredSet扩展了Set,并且指明了元素的排列顺序(升序/降序)。它有自己的特定的方法, First(), last()
subset(Object fromElement, Object toElement
), headSet(Object toElement)
返回
从集合的开头直到这个元素的子集,tailSet(Object fromElement
)返回从集合的结尾直到这个元素的子集。
下图显示了这上述接口的一个层次图:
The core collection interfaces illustration
3. Collections类
3.1) ArrayList类
ArrayList是为了解决只有在运行的时候 才能知道数组的大小的问题。它能动态地增加或减小自己的大小。其工作过程如下:数组列表以一个原始大小被创建;当超过了它的大小,类集自动增大;当对象被删除后,数组就可以缩小。
方法:
void ensueCapacity(int cap) 我们知道ArrayList对象在空间不足的时候会,会自动增加容量,但是这种再分配会花费时间,为了提高性能你可以用该方法事先人工的增加ArrayList的容量。
toArray() 为什么要把类集转换成数组的方法? 1. 对于一些特定操作,可加快处理时间;2.为了给方法传递数组,而方法不必重载去接收类集;3.为了将新的基于类集的程序与不认识类集的老程序集成。
3.2) LinkedList类
LinkedList类提供一个链表的数据结构,
构造:LinkedList(),建一个空的链表
LinkedList(Collection c),建一个由类集元素初始化的链表
方法:void addFirst(Object o),在链表头前加一个元素
void addLast(Object o),在链表尾加一个元素
Object getFirst(),得到链表的第一个元素
Object getLast(),得到链表的最后一个元素
Object removeFirst()
Object removeLast()
Object remove(int index)
注意:LinkedList 从AbstractList-> AbstractSequentialList 继承而来的,而 get(),set()方法是在接口List中定义,在抽象类AbstractList中又被继承定义为抽象的方法,在AbstractSequentialList中实现的的,又由LinkedList重载了它们。
3.3) HashSet类
继承Abstract类,实现了一个用散列表进行存储的类集。散列表通过使用称之为散列算法的机制来存储信息。散列法的优点是在于即使对于大的集合,它的操作所用的时间不变。
方法:散列表并没有定义超过它的接口和父类的方法。
散列表并没有对它的元素提供排序存储的功能。
3.4)TreeSet类
为使用树来进行存储的Set接口,对象按升序存储。
4. 通过迭代访问类集
迭代访问是一种用遍历类集中所对象的方法。有两大对象:Iterator,ListIterator
Iterator可以循环遍历类集。ListIterator可以双向循环,并可修改单元。
4.1)使用迭代函数
步骤:1)通过调用类集的iterator()方法获得对类集头的迭代函数
2)建立一个调用hasNext()方法的循环,只要hasNext()返回true,就进行循环迭代
3)在循环内部,通过调用next()方法来得到每一个元素。
5. 将用户定义的类存储在Collection中
这种例子是很重要的,类集可以存放任何类型的对象,当然也包括用户自定义的对象。比如用户自定义了一个地址类型:
class Address{
private string name;
private string street;
Address(string n, string s)
{
name=n;
street=s;
}
Public string tostring(){
Return name+”/n”+ street +”/n”;
}
}
那么,我们在应用类集的时候就可以用 linkedList来存储
LinkedList ml=new LinkedList();
//add elements to the linkder list
ml.add(new Address(“J.w.West”, “Bob”));
m1.add(new Address(“North, W-5”,”Jim”));
//检索
Iterator itr=ml.iterator();
while(itr.hasNext()){
object element=itr.next();
System.out.println(element+”/n”);
}
我们可以看到使用类集除了能存储用户自定义的类型,而且可以使用类集本身所提供的存储,检索,以及处理类集元素的诸多方法。类集对许多不同的编程问题提供了现成解决方案。所以我们大多数时候要做的工作是,针对实际情况选择合适的类集。
6. 处理映射
映射(map)是一个存储关键字和值的关联或者说是关键字/值的对象。注意映射不是类集,你可以通过.enterSet()去得到该映射的一个类集“视图”。这样你就可以使用类集的诸多方法了。
你应该从三个方面去掌握Map的知识与运用
1) 映射的接口:Map接口,Map.Entry接口,StoredMap接口
2) 类: HashMap类,TreeMap类
3) 映射类集视图的使用
7. 比较函数Comparator
1) 为什么要用Comparator?
考虑有TreeSet()类,其数据元素是按升序的情况进行存储的,那么我们现要求用降序来进行存储?如何来做呢?
注意到TreeSet有一构造为TreeSet(Comparator c),其含义为Constructs a new, empty set, sorted according to the specified comparator. All elements inserted into the set must be mutually comparable by the specified comparator: comparator.compare(e1, e2)
(构造一个空的set类对象,存储的元素是指定的Compartor类。所有的元素都是经过这个指定类的比较函数相互比较后,按大的数总是被排在set的前面。插入到set中的。)
ts2.add("E");
ts2.add("D");
ts2.add("C");
ts2.add("A");
ts2.add("B");
Incom-1,Incom-2,Incom-1,Incom-3,Incom-2,Incom-2,Incom-1,Incom1,A B C D E
ts2.add("C");
ts2.add("A");
ts2.add("B");
ts2.add("E");
ts2.add("D");
Incom-2,Incom-1,Incom1,Incom3,Incom2,Incom2,Incom1,Incom-1,A B C D E
2) 如何使用Comparator类?
8. Collections算法
Collections类提供的一些静态方法:
1) Collections.sort()
2) Collections.reversort() / Collections.sort() /
3) Collections.mix() / Collections.max()
4) static Collection synchronizedCollection(Collection c)…因为类集的实现是同步的,可以由这些同步方法提供一个同步(安全线程)拷贝。
9. Arrays(数组)
Arrays也是java.util提供的一个类,从技术上讲,尽管它不是属于类集框架,但它确实提供了类集与数组之间的桥梁。比如:
static List asList(Object[] a)
返回一个由指定数组元素组成的类集List
sort()
fill()
binarySearch()
10. 使用以前版本的类和接口(Enumeration接口/Vector接口)
Dictionary
HashTable
Properties
Stack
Vector