一、关于容器
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);
对于已排序的容器,利用折半查找法找出指定对象。