list15.docx

上传人:b****7 文档编号:10905332 上传时间:2023-02-23 格式:DOCX 页数:74 大小:52.30KB
下载 相关 举报
list15.docx_第1页
第1页 / 共74页
list15.docx_第2页
第2页 / 共74页
list15.docx_第3页
第3页 / 共74页
list15.docx_第4页
第4页 / 共74页
list15.docx_第5页
第5页 / 共74页
点击查看更多>>
下载资源
资源描述

list15.docx

《list15.docx》由会员分享,可在线阅读,更多相关《list15.docx(74页珍藏版)》请在冰豆网上搜索。

list15.docx

list15

第15章java.util第1部分:

类集框架

java.util包中包含了一些在Java2中新增加的最令人兴奋的增强功能:

类集。

一个类集(collection)是一组对象。

类集的增加使得许多java.util中的成员在结构和体系结构上发生根本的改变。

它也扩展了包可以被应用的任务范围。

类集是被所有Java程序员紧密关注的最新型的技术。

除了类集,java.util还包含了支持范围广泛的函数的各种各样的类和接口。

这些类和接口被核心的Java包广泛使用,同时当然也可以被你编写的程序所使用。

对它们的应用包括产生伪随机数,对日期和时间的操作,观测事件,对位集的操作以及标记字符串。

由于java.util具有许多特性,因此它是Java中最被广泛使用的一个包。

java.util中包含的类如下。

在Java2中新增加的一些也被列出:

AbstractCollection(Java2)

EventObject

Random

AbstractList(Java2)

GregorianCalendar

ResourceBundle

AbstractMap(Java2)

HashMap(Java2)

SimpleTimeZone

AbstractSequentialList(Java2)

HashSet(Java2)

Stack

AbstractSet(Java2)

Hashtable

StringTokenizer

ArrayList(Java2)

LinkedList(Java2)

Timer(Java2,v1.3)

Arrays(Java2)

ListResourceBundle

TimerTask(Java2,v1.3)

BitSet

Locale

TimeZone

Calendar

Observable

TreeMap(Java2)

Collections(Java2)

Properties

TreeSet(Java2)

Date

PropertyPermission(Java2)

Vector

Dictionary

PropertyResourceBundle

WeakHashMap(Java2)

java.util定义了如下的接口。

注意其中大多数是在Java2中新增加的。

Collection(Java2)

List(Java2)

Observer

Comparator(Java2)

ListIterator(Java2)

Set(Java2)

Enumeration

Map(Java2)

SortedMap(Java2)

EventListener

Map.Entry(Java2)

SortedSet(Java2)

Iterator(Java2)

ResourceBundle类,ListResourceBundle类和PropertyResourceBundle类帮助具有特定地区资源的大型程序国际化。

关于这些类的讨论,在这里从略。

授权对系统属性进行读/写的PropertyPermission类也超过了本书的讨论范围。

EventObject和EventListener类将在第20章讨论。

下面将对剩下的类和接口做详细的讨论。

由于java.util包非常大,关于它的讨论将分成两章进行。

本章讨论那些与对象的类集有关的成员。

在第16章讨论其他的类和接口。

15.1类集概述

Java的类集(Collection)框架使你的程序处理对象组的方法标准化。

在Java2出现之前,Java提供了一些专门的类如Dictionary,Vector,Stack和Properties去存储和操作对象组。

尽管这些类非常有用,它们却缺少一个集中,统一的主题。

因此例如说使用Vector的方法就会与使用Properties的方法不同。

以前的专门的方法也没有被设计成易于扩展和能适应新的环境的形式。

而类集解决了这些(以及其他的一些)问题。

类集框架被设计用于适应几个目的。

首先,这种框架是高性能的。

对基本类集(动态数组,链接表,树和散列表)的实现是高效率的。

一般很少需要人工去对这些“数据引擎”编写代码(如果有的话)。

第二点,框架必须允许不同类型的类集以相同的方式和高度互操作方式工作。

第三点,类集必须是容易扩展和/或修改的。

为了实现这一目标,类集框架被设计成包含一组标准的接口。

对这些接口,提供了几个标准的实现工具(例如LinkedList,HashSet和TreeSet),通常就是这样使用的。

如果你愿意的话,也可以实现你自己的类集。

为了方便起见,创建用于各种特殊目的的实现工具。

一部分工具可以使你自己的类集实现更加容易。

最后,增加了允许将标准数组融合到类集框架中的机制。

算法(Algorithms)是类集机制的另一个重要部分。

算法操作类集,它在Collections类中被定义为静态方法。

因此它们可以被所有的类集所利用。

每一个类集类不必实现它自己的方案,算法提供了一个处理类集的标准方法。

由类集框架创建的另一项是Iterator接口。

一个迭代程序(iterator)提供了一个多用途的,标准化的方法,用于每次访问类集的一个元素。

因此迭代程序提供了一种枚举类集内容(enumeratingthecontentsofacollection)的方法。

因为每一个类集都实现Iterator,所以通过由Iterator定义的方法,任一类集类的元素都能被访问到。

因此,稍作修改,循环通过集合的程序代码也可以被用来循环通过列表。

除了类集之外,框架定义了几个映射接口和类。

映射(Maps)存储键/值对。

尽管映射在对项的正确使用上不是“类集”,但它们完全用类集集成。

在类集框架的语言中,可以获得映射的类集“视图”(collection-view)。

这个“视图”包含了从存储在类集中的映射得到的元素。

因此,如果选择了一个映射,就可以将其当做一个类集来处理。

对于由java.util定义的原始类,类集机制被更新以便它们也能够集成到新的系统里。

所以理解下面的说法是很重要的:

尽管类集的增加改变了许多原始工具类的结构,但它却不会导致被抛弃。

类集仅仅是提供了处理事情的一个更好的方法。

最后的一点:

如果你对C++比较熟悉的话,那么你可以发现Java的类集技术与在C++中定义的标准模板库(STL)相似。

在C++中叫做容器(container),而在Java中叫做类集。

15.2类集接口

类集框架定义了几个接口。

本节对每一个接口都进行了概述。

首先讨论类集接口是因为它们决定了collection类的基本特性。

不同的是,具体类仅仅是提供了标准接口的不同实现。

支持类集的接口总结在如下的表中:

接口

描述

Collection

能使你操作对象组,它位于类集层次结构的顶层

List

扩展Collection去处理序列(对象的列表)

Set

扩展Collection去处理集合,集合必须包含唯一元素

SortedSet

扩展Set去处理排序集合

除了类集接口之外,类集也使用Comparator,Iterator和ListIterator接口。

关于这些接口将在本章后面做更深入的描述。

简单地说,Comparator接口定义了两个对象如何比较;Iterator和ListIterator接口枚举类集中的对象。

为了在它们的使用中提供最大的灵活性,类集接口允许对一些方法进行选择。

可选择的方法使得使用者可以更改类集的内容。

支持这些方法的类集被称为可修改的(modifiable)。

不允许修改其内容的类集被称为不可修改的(unmodifiable)。

如果对一个不可修改的类集使用这些方法,将引发一个UnsupportedOperationException异常。

所有内置的类集都是可修改的。

下面讨论类集接口。

15.2.1类集接口

Collection接口是构造类集框架的基础。

它声明所有类集都将拥有的核心方法。

这些方法被总结在表15-1中。

因为所有类集实现Collection,所以熟悉它的方法对于清楚地理解框架是必要的。

其中几种方法可能会引发一个UnsupportedOperationException异常。

正如上面解释的那样,这些发生在当类集不能被修改时。

当一个对象与另一个对象不兼容,例如当企图增加一个不兼容的对象到一个类集中时。

将产生一个ClassCastException异常。

表15-1由Collection定义的方法

方法

描述

booleanadd(Objectobj)

将obj加入到调用类集中。

如果obj被加入到类集中了,则返回true;如果obj已经是类集中的一个成员或类集不能被复制时,则返回false

booleanaddAll(Collectionc)

将c中的所有元素都加入到调用类集中,如果操作成功(也就是说元素被加入了),则返回true;否则返回false

voidclear()

从调用类集中删除所有元素

booleancontains(Objectobj)

如果obj是调用类集的一个元素,则返回true,否则,返回false

续表

方法

描述

booleancontainsAll(Collectionc)

如果调用类集包含了c中的所有元素,则返回true;否则,返回false

booleanequals(Objectobj)

如果调用类集与obj相等,则返回true;否则返回false

inthashCode()

返回调用类集的散列码

booleanisEmpty()

如果调用类集是空的,则返回true;否则返回false

Iteratoriterator()

返回调用类集的迭代程序

Booleanremove(Objectobj)

从调用类集中删除obj的一个实例。

如果这个元素被删除了,则返回true;否则返回false

BooleanremoveAll(Collectionc)

从调用类集中删除c的所有元素。

如果类集被改变了(也就是说元素被删除了),则返回true;否则返回false

BooleanretainAll(Collectionc)

删除调用类集中除了包含在c中的元素之外的全部元素。

如果类集被改变了(也就是说元素被删除了),则返回true,否则返回false

intsize()

返回调用类集中元素的个数

Object[]toArray()

返回一个数组,该数组包含了所有存储在调用类集中的元素。

数组元素是类集元素的拷贝

Object[]toArray(Objectarray[])

返回一个数组,该数组仅仅包含了那些类型与数组元素类型匹配的类集元素。

数组元素是类集元素的拷贝。

如果array的大小与匹配元素的个数相等,它们被返回到array。

如果array的大小比匹配元素的个数小,将分配并返回一个所需大小的新数组,如果array的大小比匹配元素的个数大,在数组中,在类集元素之后的单元被置为null。

如果任一类集元素的类型都不是array的子类型,则引发一个ArrayStoreException异常

调用add( )方法可以将对象加入类集。

注意add( )带一个Object类型的参数。

因为Object是所有类的超类,所以任何类型的对象可以被存储在一个类集中。

然而原始类型可能不行。

例如,一个类集不能直接存储类型int,char,double等的值。

当然如果想存储这些对象,也可以使用在第14章中介绍的原始类型包装器之一。

可以通过调用addAll( )方法将一个类集的全部内容增加到另一个类集中。

可以通过调用remove( )方法将一个对象删除。

为了删除一组对象,可以调用removeAll( )方法。

调用retainAll( )方法可以将除了一组指定的元素之外的所有元素删除。

为了清空类集,可以调用clear( )方法。

通过调用contains( )方法,可以确定一个类集是否包含了一个指定的对象。

为了确定一个类集是否包含了另一个类集的全部元素,可以调用containsAll( )方法。

当一个类集是空的时候,可以通过调用isEmpty( )方法来予以确认。

调用size( )方法可以获得类集中当前元素的个数。

toArray( )方法返回一个数组,这个数组包含了存储在调用类集中的元素。

这个方法比它初看上去的能力要更重要。

经常使用类数组语法来处理类集的内容是有优势的。

通过在类集和数组之间提供一条路径,可以充分利用这两者的优点。

调用equals( )方法可以比较两个类集是否相等。

“相等”的精确含义可以不同于从类集到类集。

例如,可以执行equals( )方法以便用于比较存储在类集中的元素的值,换句话说,equals( )方法能比较对元素的引用。

一个更加重要的方法是iterator( ),该方法对类集返回一个迭代程序。

正如你将看到的那样,当使用一个类集框架时,迭代程序对于成功的编程来说是至关重要的。

15.2.2List接口

List接口扩展了Collection并声明存储一系列元素的类集的特性。

使用一个基于零的下标,元素可以通过它们在列表中的位置被插入和访问。

一个列表可以包含复制元素。

除了由Collection定义的方法之外,List还定义了一些它自己的方法,这些方法总结在表15-2中。

再次注意当类集不能被修改时,其中的几种方法引发UnsupportedOperationException异常。

当一个对象与另一个不兼容,例如当企图将一个不兼容的对象加入一个类集中时,将产生ClassCastException异常。

表15-2由List定义的方法

方法

描述

voidadd(intindex,Objectobj)

将obj插入调用列表,插入位置的下标由index传递。

任何已存在的,在插入点以及插入点之后的元素将前移。

因此,没有元素被覆盖

booleanaddAll(intindex,Collectionc)

将c中的所有元素插入到调用列表中,插入点的下标由index传递。

在插入点以及插入点之后的元素将前移。

因此,没有元素被覆盖。

如果调用列表改变了,则返回true;否则返回false

Objectget(intindex)

返回存储在调用类集内指定下标处的对象

intindexOf(Objectobj)

返回调用列表中obj的第一个实例的下标。

如果obj不是列表中的元素,则返回-1

intlastIndexOf(Objectobj)

返回调用列表中obj的最后一个实例的下标。

如果obj不是列表中的元素,则返回-1

ListIteratorlistIterator()

返回调用列表开始的迭代程序

ListIteratorlistIterator(intindex)

返回调用列表在指定下标处开始的迭代程序

Objectremove(intindex)

删除调用列表中index位置的元素并返回删除的元素。

删除后,列表被压缩。

也就是说,被删除元素后面的元素的下标减一

Objectset(intindex,Objectobj)

用obj对调用列表内由index指定的位置进行赋值

ListsubList(intstart,intend)

返回一个列表,该列表包括了调用列表中从start到end–1的元素。

返回列表中的元素也被调用对象引用

对于由Collection定义的add( )和addAll( )方法,List增加了方法add(int,Object)和addAll(int,Collection)。

这些方法在指定的下标处插入元素。

由Collection定义的add(Object)和addAll(Collection)的语义也被List改变了,以便它们在列表的尾部增加元素。

为了获得在指定位置存储的对象,可以用对象的下标调用get( )方法。

为了给类表中的一个元素赋值,可以调用set( )方法,指定被改变的对象的下标。

调用indexOf( )或lastIndexOf( )可以得到一个对象的下标。

通过调用subList( )方法,可以获得列表的一个指定了开始下标和结束下标的子列表。

正如你能想象到的,subList( )方法使得列表处理十分方便。

15.2.3集合接口

集合接口定义了一个集合。

它扩展了Collection并说明了不允许复制元素的类集的特性。

因此,如果试图将复制元素加到集合中时,add( )方法将返回false。

它本身并没有定义任何附加的方法。

15.2.4SortedSet接口

SortedSet接口扩展了Set并说明了按升序排列的集合的特性。

除了那些由Set定义的方法之外,由SortedSet接口说明的方法列在表15-3中。

当没有项包含在调用集合中时,其中的几种方法引发NoSuchElementException异常。

当对象与调用集合中的元素不兼容时,引发ClassCastException异常。

如果试图使用null对象,而集合不允许null时,引发NullPointerException异常。

表15-3由SortedSet定义的方法

方法

描述

Comparatorcomparator()

返回调用被排序集合的比较函数,如果对该集合使用自然顺序,则返回null

Objectfirst()

返回调用被排序集合的第一个元素

SortedSetheadSet(Objectend)

返回一个包含那些小于end的元素的SortedSet,那些元素包含在调用被排序集合中。

返回被排序集合中的元素也被调用被排序集合所引用

Objectlast()

返回调用被排序集合的最后一个元素

SortedSetsubSet(Objectstart,Objectend)

返回一个SortedSet,它包括了从start到end–1的元素。

返回类集中的元素也被调用对象所引用

SortedSettailSet(Objectstart)

返回一个SortedSet,它包含了那些包含在分类集合中的大于等于start的元素。

返回集合中的元素也被调用对象所引用

SortedSet定义了几种方法,使得对集合的处理更加方便。

调用first( )方法,可以获得集合中的第一个对象。

调用last( )方法,可以获得集合中的最后一个元素。

调用subSet( )方法,可以获得排序集合的一个指定了第一个和最后一个对象的子集合。

如果需要得到从集合的第一个元素开始的一个子集合,可以使用headSet( )方法。

如果需要获得集合尾部的一个子集合,可以使用tailSet( )方法。

15.3Collection类

现在,你已经熟悉了类集接口,下面开始讨论实现它们的标准类。

一些类提供了完整的可以被使用的工具。

另一些类是抽象的,提供主框架工具,作为创建具体类集的起始点。

没有Collection类是同步的,但正如你将在本章后面看到的那样,有可能获得同步版本。

标准的Collection类总结在下面的表中。

描述

AbstractCollection

实现大多数Collection接口

AbstractList

扩展AbstractCollection并实现大多数List接口

AbstractSequentialList

为了被类集使用而扩展AbstractList,该类集使用连续而不是随机方式访问其元素

LinkedList

通过扩展AbstractSequentialList来实现链接表

ArrayList

通过扩展AbstractList来实现动态数组

AbstractSet

扩展AbstractCollection并实现大多数Set接口

HashSet

为了使用散列表而扩展AbstractSet

TreeSet

实现存储在树中的一个集合。

扩展AbstractSet

注意:

除了Collection类外,还有几个从以前版本遗留下来的类,如Vector,Stack和Hashtable均被重新设计成支持类集的形式。

这些内容将在本章后面讨论。

下面讨论具体的Collection类,举例说明它们的用法。

15.3.1ArrayList类

ArrayList类扩展AbstractList并执行List接口。

ArrayList支持可随需要而增长的动态数组。

在Java中,标准数组是定长的。

在数组创建之后,它们不能被加长或缩短,这也就意味着你必须事先知道数组可以容纳多少元素。

但是,你直到运行时才能知道需要多大的数组。

为了解决这个问题,类集框架定义了ArrayList。

本质上,ArrayList是对象引用的一个变长数组。

也就是说,ArrayList能够动态地增加或减小其大小。

数组列表以一个原始大小被创建。

当超过了它的大小,类集自动增大。

当对象被删除后,数组就可以缩小。

注意:

动态数组也被从以前版本遗留下来的类Vector所支持。

关于这一点,将在本章后面介绍。

ArrayList有如下的构造函数:

ArrayList( )

ArrayList(Collectionc)

ArrayList(intcapacity)

其中第一个构造函数建立一个空的数组列表。

第二个构造函数建立一个数组列表,该数组列表由类集c中的元素初始化。

第三个构造函数建立一个数组列表,该数组有指定的初始容量(capacity)。

容量是用于存储元素的基本数组的大小。

当元素被追加到数组列表上时,容量会自动增加。

下面的程序展示了ArrayList的一个简单应用。

首先创建一个数组列表,接着添加类型String的对象(回想一个引用字符串被转化成一个字符串(String)对象)。

接着列表被显示出来。

将其中的一些元素删除后,再一次显示列表。

//DemonstrateArrayList.

importjava.util.*;

classArrayListDemo{

publicstaticvoidmain(Stringargs[]){

//createanarraylist

ArrayListal=newArrayList();

System.out.println("Initialsizeofal:

"+

al.size());

//addelementstothearraylist

al.add("C");

al.add("A");

al.add("E");

al.add("B");

al.add("D");

al.add("F");

al.add(1,"A2");

System.out.println("Sizeofalafteradditions:

"+

al.size());

//displaythearraylist

System.out.println("Contentsofal:

"+al);

//Removeelementsfromthearraylist

al.remove("F");

al.remove

(2);

System.out.println("Sizeofalafterdeletions:

"+

al.size());

System.out.pr

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 历史学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1