一、关于容器

1.1 容器的定义

容器(Collection)即为集合,在java中指对象的集合,容器中存放的都只能是对象,实际上为存放对象的指针(头部地址)。

1.2 为什么需要容器

为了在编程中对若干个对象进行集中处理,当然数组也可以实现这个需求,但是数组存在两个硬伤:

a.数组中元素的类型必须相同;b.数组的长度难以扩充。

加入A是一个类型,则 A arr_A[ ] = new A[10]; 表示在内存中分配了一个数组,数组的长度是10,则对于该数组来讲:

(1)数组中存放的元素只能是A的对象;

(2)如果想要扩充这个数组,只能重新建立一个长度更长的数组,并用System.arraycopy()函数把原数组的内容copy到新数组,这样做的话十分耗费cpu资源和内存空间。

但如果使用容器的话便可以解决这两个问题,也就是说,一个容器可以存放不同类型的对象(实际上是对象的指针),而且可以灵活扩充容器的长度。

二、容器的分类

数学上,容器可以分为三种:

1.集(Set)

Set相当于数学上的集合,集合中的所有元素都是无序的,而且不允许出现重复元素。

2.列表(List)

List相当于代数里面的队列,列表的元素是有序的,而且允许包含重复成员。

当然在java中LIst也可以分为数组列表(ArrayList)和链表(LinkedList),它们两者的使用方法类似,但是内存存储机制不同。

3.映射(Map)

Map保存所谓的“键值对”(Key-Value)信息,映射中不能出现重复的键(Key),每个键最多只能映射一个值。

 

java中sun公司为上面三个容器类型设计了三个对应的接口(interface),这三个接口分别是Set、List、Map。

关系框架为:

对于Set来讲,Set接口集成了Collection接口,HashSet这个容器(类)实现了Set接口。

而ArrayList和LinkedList都实现了List接口,List接口也继承自Collection接口。

HashMap容器则实现了Map接口,而Map接口并不继承与Collection接口!!!

由此看出,Java里的容器是基于接口(interface)构建的:

*Collection接口定义了存取一组对象的方法,其子接口Set和List分别定义了存储方式。

*Map接口定义了存储(Key-value)映射对的方法。

很多时候,大家还会见到另一容器Vector,其实Vector也是List容器的一种,但是Vector支持线程同步(里面的方法都是sychronized的),也就是允许多个线程同时搓澡1个Vector容器而不丢失数据。(看书!!!)

而ArrayList并不是同步的。

三、容器的若干个常用方法

容器作为一个类,当然有若干个常用的成员方法:

3.1 int size()

返回Collection中元素的个数

3.2 boolean containsAll(Collection c);

判断容器中是否包含另一个容器的所有元素,这里的元素指的是对象的指针,也就是对象本身。

3.3 boolean add(Object e);

把一个对象添加到容器中,这个方法是每种容器必有的方法。

3.4 boolean remove(Object e);

移除容器中首次出现的制定对象,因为List容器根据次序不同允许存在重复的对象。

3.5 get(int index);

获得容器中第index个元素,这个方法在List容器中十分常用,但是并不适用于Set容器,因为Set容器中元素是无序的。

3.6 Iterator iterator();

一些无序的容器很难通过循环来遍历元素,这时我们可以利用迭代器来遍历容器元素。

3.6 Object[ ] toArray();

容器不是数组,不能用下标来访问容器的元素,这个方法可以返回一个包含容器所有元素的数组。

3.8 重写容器元素的toString()方法

很多时候,我们需要循环输出容器元素的对象:

for(……){

      System.out.println(arr1.get(i));

}

而println方法是输出对象的toString()方法,toString()方法在基类(Object)中被定义成输出对象的类名+hashcode(),而很多时候我们需要的是输出对象的其他有用信息(例如关键成员的值)。

所以强烈建议:为所有可能放入容器的类重写toString()方法。

四、Collections类

上面提到Collection其实是一个接口,但是java里也存在一个类jiaoCollections,而这个Collections也是跟容器有关的。我们常用的容器,例如ArrayList、HashSet、LinkedList等都是基于Collection接口实现的,所以Collections并不是上述容器的超类(父类)。实际上,在java的容器(例如ArrayList、LinkList)类只提供了一些简单的操作方法,如add()、get()、size()等,而一些复杂的功能,如排序(sort)、倒置(reverst)则没有提供。

所以java提供了另一个类Collections,集合了很多对容器进行复杂操作的静态方法,这就是Collectiosn类的意义。

下面列举若干Collections类的常用方法。

4.1 void sort(List);

对List容器内的元素排序,前提是容器内元素的类已经实现了Comparable接口(可比较的)。

4.2 void Shuffle(List);

对Lis容器的元素进行随机排序。

4.3 void reverst(List);

传说中的倒置,对List容器内的元素进行逆排序,一般没什么用。

4.4 void Fill(List, Object);

把容器内的所有元素都替换为1个指定对象(Object)

4.5 void Copy(List dest, List src);

把容器src里的内容复制到dest容器

4.6 int bianrySearch(List, Object);

对于已排序的容器,利用折半查找法找出指定对象。