11Java集合.docx

上传人:b****8 文档编号:10652838 上传时间:2023-02-22 格式:DOCX 页数:61 大小:1.49MB
下载 相关 举报
11Java集合.docx_第1页
第1页 / 共61页
11Java集合.docx_第2页
第2页 / 共61页
11Java集合.docx_第3页
第3页 / 共61页
11Java集合.docx_第4页
第4页 / 共61页
11Java集合.docx_第5页
第5页 / 共61页
点击查看更多>>
下载资源
资源描述

11Java集合.docx

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

11Java集合.docx

11Java集合

11Java集合

11.1认识集合类

集合(或容器)表示保存一个对象组的单个对象,其它对象被认为是它的元素。

集合与数组的不同在于,它是大小可变的序列,而且元素类型可以不受限定,只要是引用类型。

对象数组中包含一组对象,但是对象数组使用的时候存在一个长度的限制,那么集合是专门解决这种限制的,使用集合可以方便的向数组中增加任意多个数据。

集合类使用初始容量和加载因子调整自己的大小。

集合类全部支持泛型,是一种数据安全的用法。

Java集合框架定义了几个接口。

这些集合接口决定了集合实现类的基本特性。

对于不同的集合实现类提供了这些标准接口的不同实现。

Java集合接口如表11-1所示:

表11-1Java集合接口

Java集合类库的用途就是“保存对象”,主要分为两类:

Collection:

层次结构中的根接口。

Collection表示一组对象,这些对象也称为collection的元素。

一些collection允许有重复的元素,而另一些则不允许。

一些collection是有序的,而另一些则是无序的。

JDK不提供此接口的任何直接实现,它提供更具体的子接口(如Set和List)实现。

此接口通常用来传递collection,并在需要最大普遍性的地方操作这些collection。

Collection常见的子接口如图11-1:

图11-1Collection接口继承图

Collection:

一组没有顺序的对象,允许出现相同的元素对象。

Set:

一组没有顺序的对象(离散),不允许重复相同的元素。

SortedSet:

是一个按照升序排列元素的Set。

List:

一组有插入顺序的对象,允许重复相同的元素。

关于Collection更为详细的继承图谱如图11-2:

图11-2Collection接口以及实现类继承图谱

Map:

一组成对的“键—值”对象,允许你使用键来查找值。

ArrayList允许你使用数字来查找值,因此在某种意义上讲,它将数组与对象关联在一起。

映射表允许我们使用一个对象来查找某个对象,它被称为“关联数组”,因为它将某些对象与另外一些对象关联在一起,也被称为“字典”,因为你可以使用键对象来查找值对象。

Map常见的子接口如图11-3:

图11-3Map接口继承图

关于Map更为详细的继承图谱如图11-4:

图11-4Map接口以及实现类继承图谱

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

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

简单地说,Comparator接口定义了两个对象比较方法。

Iterator和ListIterator接口类集中的对象。

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

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

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

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

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

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

11.2Collection接口及其子接口

Collection接口是构造类集框架的基础,是保存单值集合的最大父接口。

Java没有提供该接口的直接实现类。

Collection接口定义如下:

publicinterfaceCollectionextendsIterable

JDK1.5之后为Collection接口增加了泛型声明。

所有的类集操作都存放在java.util包中。

在一般的开发中,往往很少去直接使用Collection接口进行开发,而基本上都是使用其子接口。

常见的Collection子接口有:

List、Set、Queue、SortedSet。

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

在JDK1.5之前,这些方法被总结在表11-2(A)中,在JDK1.5之后,增加了泛型,这些方法被总结在表11-2(B)中。

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

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

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

当一个对象与另一个对象不兼容,例如:

当企图增加一个不兼容的对象到一个类集中时,将产生一个ClassCastException异常。

表11-2(A)JDK1.5之前Collection接口的方法定义

表11-2(B)JDK1.5之后Collection接口的方法定义

(注:

关于JDK1.5后方法的具体说明可以参考JDK1.5之前的方法说明)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

我们可以通过它遍历整个集合。

除此之外还可以利用foreach结构遍历。

11.2.1List接口

List是Collection的子接口,它强调元素的插入顺序,可以包含重复的元素。

它扩展了Collection接口并提供了按索引访问元素的方式,可以利用索引下标在集合的指定位置插入、删除和访问元素。

实现List接口的类有:

ArrayList、LinkedList、Stack、Vector。

其中Stack和Vector是早期集合类,他们是线程安全(同步的)集合类,一般性能会稍慢于非同步的集合类。

ArrayList是利用数组实现的,LinkedList是利用链表实现的。

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

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

当一个对象与另一个不兼容,例如:

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

表11-3由List定义的方法

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

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

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

为了获得指定位置的存储对象,可以利用get(下标)的形式得到。

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

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

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

对于List而言,除了有foreach遍历方式和迭代器遍历方式之外,还可以利用get()方法通过循环完成遍历,循环次数由size()决定,此遍历操作是List接口独有的。

11.2.2Set接口

Set继承于Collection,由于其不允许元素重复,没有顺序概念,相对于Collection无需扩展方法,限制add类方法不要放入重复元素就可以(set判断两个对象是否相等的标准是两个对象通过equals方法比较相等,并且两个对象的hashCode()方法返回值相同)。

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

实际创建时要使用Set的实现类,包括EnumSet,HashSet,LinkedHashSet,TreeSet,其中LinkedHashSet体现插入顺序,TreeSet体现了元素排序。

性能方面“HashSet>LinkedHashSet>TreeSet”,但是对于遍历查找则可能相反。

11.2.2.1SortedSet接口

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

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

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

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

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

表11-4由SortedSet定义的方法

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

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

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

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

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

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

11.3Collection接口及其子接口的常见实现类

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

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

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

没有一个Collection接口是同步的,在本章后面看到的那样,有可能获得同步版本。

标准的Collection实现类总结表11-5中。

表11-5Collection实现类

注意:

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

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

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

11.3.1ArrayList类

ArrayList类扩展AbstractList并支持List接口。

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

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

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

但是,一般情况下,只有在运行时才能知道需要多大的数组。

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

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

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

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

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

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

注意:

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

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

ArrayList有如下的构造方法:

ArrayList()

ArrayList(Collectionc)

ArrayList(intcapacity)

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

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

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

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

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

下面的程序是ArrayList的一个简单应用。

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

接着列表被显示出来。

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

范例:

ArrayListDemo.java

importjava.util.*;

publicclassArrayListDemo{

publicstaticvoidmain(Stringargs[]){

//创建一个ArrarList对象

ArrayListal=newArrayList();

System.out.println("a1的初始化大小:

"+al.size());

//向ArrayList对象中添加新内容

al.add("C");//0位置

al.add("A");//1位置

al.add("E");//2位置

al.add("B");//3位置

al.add("D");//4位置

al.add("F");//5位置

//把A2加在ArrayList对象的第2个位置

al.add(1,"A2");//加入之后的内容:

CA2AEBDF

System.out.println("a1加入元素之后的大小:

"+al.size());

//显示Arraylist数据

System.out.println("a1的内容:

"+al);

//从ArrayList中移除数据

al.remove("F");

al.remove

(2);//CA2EBD

System.out.println("a1删除元素之后的大小:

"+al.size());

System.out.println("a1的内容:

"+al);

}

}

输出结果:

a1的初始化大小:

0

a1加入元素之后的大小:

7

a1的内容:

[C,A2,A,E,B,D,F]

a1删除元素之后的大小:

5

a1的内容:

[C,A2,E,B,D]

注意a1开始时是空的,当添加元素后,它的大小增加了。

当有元素被删除后,它的大小又会变小。

在前面的例子中,使用由toString()方法提供的默认的转换显示类集的内容,toString()方法是从AbstractCollection继承下来的。

它对简短的程序来说是足够了,但很少使用这种方法去显示实际中的类集的内容。

通常编程者会提供自己的输出程序。

但在下面的几个例子中,仍将采用由toString()方法创建的默认输出。

尽管当对象被存储在ArrayList对象中时,其容量会自动增加。

然而,也可以通过调用ensureCapacity()方法来人工地增加ArrayList的容量。

如果事先知道将在当前能够容纳的类集中存储许许多多的内容时,你可能会想这样做。

在开始时,通过一次性地增加它的容量,就能避免后面的再分配。

因为再分配是很花时间的,避免不必要的处理可以提高性能。

范例:

ArrayListToArray.java

importjava.util.*;

publicclassArrayListToArray{

publicstaticvoidmain(Stringargs[]){

//创建一个ArrayList对象al

ArrayListal=newArrayList();

//向ArrayList中加入对象

al.add(newInteger

(1));

al.add(newInteger

(2));

al.add(3);

al.add(4);

System.out.println("ArrayList中的内容:

"+al);

//得到对象数组

Objectia[]=al.toArray();

intsum=0;

//计算数组内容

for(inti=0;i

sum+=((Integer)ia[i]).intValue();

System.out.println("数组累加结果是:

"+sum);

}

}

输出结果:

ArrayList中的内容:

[1,2,3,4]

数组累加结果是:

10

程序开始时创建一个整数的类集。

接下来,toArray()方法被调用,它获得了一个Object对象数组。

这个数组的内容被置成整型(Integer),接下来对这些值进行求和操作。

11.3.2LinkedList类

LinkedList类扩展了AbstractSequentialList类并实现List接口。

它提供了一个链接列表的数据结构。

它具有如下的两个构造方法,说明如下:

LinkedList()

LinkedList(Collectionc)

第一个构造方法建立一个空的链接列表。

第二个构造方法建立一个链接列表,该链接列表由另一个集合c中的元素初始化。

除了它继承的方法之外,LinkedList类本身还定义了一些有用的方法,这些方法主要用于操作和访问列表。

使用addFirst()方法或offerFirst()方法或add(0,obj)方法或push()方法可以在列表头增加元素。

它们的形式如下所示:

voidaddFirst(Eobj)

voidadd(intindex,Ee)

booleanofferFirst(Ee)

voidpush(Ee)

使用addLast()方法或offer()方法或offerLast()可以在列表的尾部增加元素。

它们的形式如下所示:

voidaddLast(Eobj)

booleanoffer(Ee)

booleanofferLast(Fe)

调用getFirst()方法或element()方法或get(0)方法或peek()方法或peekFirst()方法可以获得第一个元素,且不从列表中删除该元素。

它们的形式如下所示:

EgetFirst()

Eelement()

Eget(intindex)

Epeek()

EpeekFirst()

调用getLast()方法或get(link.size()-1)方法或peekLase()方法可以得到最后一个元素。

注意这些方法都是获得但不移除。

它们的形式如下所示:

EgetLast()

Eget(intindex)

EpeekLast

为了获取并删除第一个元素,可以使用remove()或remove(0)或removeFirst()或poll()或pollFirst()或pop()方法。

它们的形式如下所示:

Eremove()

Eremove(intindex)

EremoveFirst()

Epoll()

EpollFrist()

Epop()

为了删除最后一个元素,可以调用remove(link.size()-1)或removeLast()或pollLast()方法。

它们的形式如下所示:

Eremove(intindex)

EremoveLast()

EpollLast()

调用removeFirstOccurrence(e)方法用于删掉从头到尾找第一次出现该元素的元素,调用removeLastOccurrence(e)方法用于删掉从后往前找第一次出现该元素的元素。

它们的形式如下所示:

booleanremoveFirstOccurrence(Objecte)

booleanremoveLastOccurrence(Objecte)

利用正常迭代器Iterator可以正序遍历整个集合,利用iterator()方法:

//LinkedList正常迭代器访问方式

Iteratorit=link.iterator();

while(it.hasNext()){

System.out.print(it.next()+"");

}

System.out.println();

利用ListIterator可以从指定位置向前或向后遍历集合,利用listIterator(intindex)方法:

//LinkedList从指定位置开始向后遍历

ListIteratorlit=link.listIterator(3);

while(lit.hasNext()){

System.out.print(lit.next()+"");

}

System.out.println();

//LinkedList从指定位置开始向前遍历

ListIteratorrlit=link.listIterator(3);

while(rlit.hasPrevious()){

System.out.print(rlit.previous()+"");

}

System.out.println();

利用正常迭代器Iterator可以逆序遍历整个集合,利用descendingIterator()方法:

//LinkedList反向迭代器

Iteratordit=link.descendingIterator();

while(dit.hasNext()){

System.out.print(dit.next()+"");

}

System.out.println();

下面的程序举例是对几个LinkedList支持的方法的说明:

范例:

LinkedListDemo.java

importjava.util.*;

publicclassLinkedListDemo{

publicstaticvoidmain(Stringargs[]){

//创建LinkedList对象

LinkedListll=newLinkedList();

//加入元素到LinkedList中

ll.add("F");

ll.add("B");

ll.add("D");

ll.add("E");

ll.add("C");

//在链表的最后个位置加上数据

ll.addLast("Z");

//在链表的第一个位置上加入数据

ll.addFirst("A");

//在链表第二个元素的位置上加入数据

ll.add(1,"A2");

System.out.println("ll最初的内容:

"+ll);

//从linkedlist中移除元素

ll.remove("F");

ll.remove

(2);

System.out.println("从ll中移除内容之后:

"+ll);

//移除第一个和最后一个元素

ll.removeFirst();

展开阅读全文
相关搜索

当前位置:首页 > 求职职场 > 笔试

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

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