JAVA集合框架之List 下载本文

www.cdbdqn.cn

JAVA集合框架之List

1.先介绍集合框架:

Java,是由Sun公司于1995年推出的编程语言。用Java实现的HotJava浏览器(支持Java applet)显示了Java的魅力:跨平台、动态的Web、Internet计算。从此,Java被广泛接受并推动了Web的迅速发展,常用的浏览器现在均支持Java applet。集合框架是为表示和操作集合而规定的一种统一的标准的体系结构。任何集合框架都包含三大块内容:对外的接口、接口的实现和对集合运算的算法。

框架的益处 查看详情 减少设计辛劳

集合框架通过提供有用的数据结构和算法使你能集中注意力于你的程序的重要部分上,而不是为了让程序能正常运转而将注意力于低层设计上。通过这些在无关API之间的简易的互用性,使你免除了为改编对象或转换代码以便联合这些API而去写大量的代码。

提高速度质量 查看详情

集合框架通过提供对有用的数据结构和算法的高性能和高质量的实现使你的程序速度和质量得到提高。因为每个接口的实现是可互换的,所以你的程序可以很容易的通过改变一个实现而进行调整。另外,你将可以从写你自己的数据结构的苦差事中解脱出来,从而有更多时间关注于程序其它部分的质量和性能。

API缺点 查看详情

许多API天生的有对集合的存储和获取。在过去,这样的API都有一些子API帮助操纵它的集合内容,因此在那些特殊的子API之间就会缺乏一致性,你也不得不从零开始学习,并且在使用时也很容易犯错。而标准集合框架接口的出现使这个问题迎刃而解。

集合框架的复用

对于遵照标准集合框架接口的新的数据结构天生即是可复用的。同样对于操作一个实现了这些接口的对象的算法也是如此。

有了这些优点,并通过合理的使用,它就会成为程序员的一种强大的工具。不过,从历史上来看,集合大多其结构相当复杂,也就给它们一个造成极不合理的学习曲线的坏名声。但是,希望Java2的集合框架能缩短你的学习曲线,从而快速掌握它。

在许多高级语言中的数组其实也是集合的一种简单实现,比如C,C++,Pascal和Java。数组保存着相同类型的多个值,它的长度在数组被创建时就固定下来,建立之后就无法改变。如果你需要一种大小能动态改变的存储结构,数组就不适合了,这时集合框架就有了用武之地了。 2.List

Collection 查看详情

Collection接口提供了一组操作成批对象的方法

它提供了基本操作如添加、删除。它也支持查询操作如是否为空isEmpty()方法等。为了支持对Collection进行独立操作,Java的集合框架给出了一个Iterator,它使得你可以泛型操作一个Collection,而不需知道这个Collection的具体实现类型是什么。它的功能与Java1中的Enumeration类似,只是更易掌握和使用,功能也更强大。在建立集合框架时,Sun的开发团队考虑到需要提供一些灵活的接口,用来操作成批的元素,又为了设计的简便,就把那些对集合进行可选操作的方法与基本方法放到了一起。因为一个接口的实现者必须提供对接口中定义的所有方法的实现,这就需要一种途径让调用者知道它正在调用的可选方法当前不支持。最后开发团队选择使用一种信号,也即抛出一种不支持操作例外(UnsupportedOperationException),

www.cdbdqn.cn

如果你在使用一个Collection中遇到一个上述的例外,那就意味着你的操作失败,比如你对一个只读Collection添加一个元素时,你就会得到一个不支持操作例外。在你实现一个集合接口时,你可以很容易的在你不想让用户使用的方法中抛出UnsupportOperationException来告诉使用者这个方法当前没有实现,UnsupportOperationException是RuntimeException的一个扩展。

另外Java2的容器类库还有一种Fail fast的机制。比如你正在用一个Iterator遍历一个容器中的对象,这时另外一个线程或进程对那个容器进行了修改,那么再用next()方法时可能会有灾难性的后果,而这是你不愿看到的,这时就会引发一个ConcurrentModificationException例外。这就是fail-fast。Collection的功能 下面这张表给出了Collection的所有功能,也就是你能用Set和List做什么事(不包括从Object自动继承过来的方法)。(List还有一些额外的功能。)Map不是继承Collection的,所以我们会区别对待。 boolean add(Object):确保容器能持有你传给它的那个参数。如果没有把它加进去,就返回false。(这是个“可选”的方法,本章稍后会再作解释。)

boolean addAll(Collection):加入参数Collection所含的所有元素。只要加了元素,就返回true。 void clear():清除容器所保存的所有元素。(“可选”)

boolean contains(Object):如果容器持有参数Object,就返回true。

boolean containsAll(Collection):如果容器持有参数Collection所含的全部元素,就返回true。 boolean isEmpty():如果容器里面没有保存任何元素,就返回true。

Iterator iterator():返回一个可以在容器的各元素之间移动的Iterator。

boolean removeAll(Collection):删除容器里面所有参数Collection所包含的元素。只要删过东西,就返回true。(“可选”)

boolean retainAll(Collection):只保存参数Collection所包括的元素(集合论中“交集”的概念)。如果发生过变化,则返回true。(“可选”) int size():返回容器所含元素的数量。

Object[] toArray():返回一个包含容器中所有元素的数组。

Object[] toArray(Object[] a):返回一个包含容器中所有元素的数组,且这个数组不是普通的Object数组,它的类型应该同参数数组a的类型相同(要做类型转换)。

注意,这里没有能进行随机访问的get()方法。这是因为Collection还包括Set。而Set有它自己的内部顺序(因此随机访问是毫无意义的)。所以如果你要检查Collection的元素,你就必须使用迭代器。

接下来讲List, Set和Map的各种实现了,每讲一种容器,我都会(用星号)告诉你默认情况下应该选用哪种实现。

List接口对Collection进行了简单的扩充

它的具体实现类常用的有ArrayList和LinkedList。你可以将任何东西放到一个List容器中,并在需要时从中取出。ArrayList从其命名中可以看出它是一种类似数组的形式进行存储,因此它的随机访问速度极快,而LinkedList的内部实现是链表,它适合于在链表中间需要频繁进行插入和删除操作。在具体应用时可以根据需要自由选择。

List的基本用法是相当简单的。虽然绝大多数时候,你只是用add()加对象,用get()取对象,用iterator()获取这个序列的Iterator,但List还有一些别的很有用的方法。

List(接口)

:List的最重要的特征就是有序;它会确保以一定的顺序保存元素。(注意:这里的顺序是指储存顺序和读取顺序一致,而不是按照大小排序)List在Collection的基础上添加了大量方法,使之能在序列中间插入和删除元素。(只对LinkedList推荐使用。)List可以制造ListIterator对象,你除了能用它在List的中间插入和

www.cdbdqn.cn

删除元素之外,还能用它沿两个方向遍历List。

ArrayList*:

一个用数组实现的List。能进行快速的随机访问,但是往列表中间插入和删除元素的时候比较慢。ListIterator只能用在反向遍历ArrayList的场合,不要用它来插入和删除元素,因为相比LinkedList,在ArrayList里面用ListIterator的系统开销比较高。

示例代码:

ArrayList List = new ArrayList();

for( int i=0;i<10;i++ ) //给数组增加10个Int元素 List.Add(i); //..程序做一些处理

List.RemoveAt(5);//将第6个元素移除 for( int i=0;i<3;i++ ) //再增加3个元素 List.Add(i+9); 1 2 3 4 5 6 7 Vector

Vector的操作很简单,通过addElement()加入一个对象,用elementAt()取出它,还可以查询当前所保存的对象的个数size();另外还有一个Enumeration类提供了连续操作Vector中元素的方法,这可以通过Vector中的elements()方法来获取一个Enumeration类的对象,可以用一个While循环来遍历其中的元素。用hasMoreElements()检查其中是否还有更多的元素。用nextElement()获得下一个元素。Enumeration的用意在于使你能完全不用理会你要遍历的容器的基础结构,只关注你的遍历方法,这也就使得遍历方法的重用成为可能。由于这种思想的强大功能,所以在Java2中被保留下来,不过具体实现,方法名和内部算法都改变了,这就是Java2中的Iterator以及ListIterator类。然而Enumeration的功能却十分有限,比如只能朝一个方向进行,只能读取而不能更改等。 示例代码

import java.util.Vector; import java.util.List; import java.util.Iterator; import java.util.Enumeration; /**

* @desc Vector测试函数:遍历Vector和常用API *

* @author skywang */

www.cdbdqn.cn

public class VectorTest {

public static void main(String[] args) { // 新建Vector

Vector vec = new Vector();

// 添加元素 vec.add(\ vec.add(\ vec.add(\ vec.add(\ vec.add(\

// 设置第一个元素为100 vec.set(0, \

// 将“500”插入到第3个位置 vec.add(2, \

System.out.println(\ // (顺序查找)获取100的索引

System.out.println(\ // (倒序查找)获取100的索引

System.out.println(\ // 获取第一个元素

System.out.println(\ // 获取第3个元素

System.out.println(\ // 获取最后一个元素

System.out.println(\ // 获取Vector的大小

System.out.println(\ // 获取Vector的总的容量

System.out.println(\ // 获取vector的“第2”到“第4”个元素 System.out.println(\ // 通过Enumeration遍历Vector Enumeration enu = vec.elements(); while(enu.hasMoreElements())

System.out.println(\

Vector retainVec = new Vector(); retainVec.add(\ retainVec.add(\

// 获取“vec”中包含在“retainVec中的元素”的集合 System.out.println(\ System.out.println(\

www.cdbdqn.cn

// 获取vec对应的String数组

String[] arr = (String[]) vec.toArray(new String[0]); for (String str:arr)

System.out.println(\

// 清空Vector。clear()和removeAllElements()一样! vec.clear();

// vec.removeAllElements(); // 判断Vector是否为空

System.out.println(\ } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33