📄 chapter8.htm
字号:
<br>
新集合库的所有代码示例都置于子目录newcollections下,这样便可提醒自己这些工作只对于Java
1.2有效。这样一来,我们必须用下述代码来调用程序:<br>
java c08.newcollections.SimpleCollection<br>
采用的语法与其他程序是差不多的。<br>
大家可以看到新集合属于java.util库的一部分,所以在使用时不需要再添加任何额外的import语句。<br>
main()的第一行创建了一个ArrayList对象,然后将其上溯造型成为一个集合。由于这个例子只使用了Collection方法,所以从Collection继承的一个类的任何对象都可以正常工作。但ArrayList是一个典型的Collection,它代替了Vector的位置。<br>
显然,add()方法的作用是将一个新元素置入集合里。然而,用户文档谨慎地指出add()“保证这个集合包含了指定的元素”。这一点是为Set作铺垫的,后者只有在元素不存在的前提下才会真的加入那个元素。对于ArrayList以及其他任何形式的List,add()肯定意味着“直接加入”。<br>
利用iterator()方法,所有集合都能生成一个“反复器”(Iterator)。反复器其实就象一个“枚举”(Enumeration),是后者的一个替代物,只是:<br>
(1) 它采用了一个历史上默认、而且早在OOP中得到广泛采纳的名字(反复器)。<br>
(2) 采用了比Enumeration更短的名字:hasNext()代替了hasMoreElement(),而next()代替了nextElement()。<br>
(3) 添加了一个名为remove()的新方法,可删除由Iterator生成的上一个元素。所以每次调用next()的时候,只需调用remove()一次。<br>
在SimpleCollection.java中,大家可看到创建了一个反复器,并用它在集合里遍历,打印出每个元素。<br>
<br>
8.7.1 使用Collections<br>
下面这张表格总结了用一个集合能做的所有事情(亦可对Set和List做同样的事情,尽管List还提供了一些额外的功能)。Map不是从Collection继承的,所以要单独对待。<br>
<br>
366-367页表<br>
boolean add(Object)
*保证集合内包含了自变量。如果它没有添加自变量,就返回false(假)<br>
boolean addAll(Collection)
*添加自变量内的所有元素。如果没有添加元素,则返回true(真)<br>
void clear() *删除集合内的所有元素<br>
boolean contains(Object) 若集合包含自变量,就返回“真”<br>
boolean containsAll(Collection)
若集合包含了自变量内的所有元素,就返回“真”<br>
boolean isEmpty() 若集合内没有元素,就返回“真”<br>
Iterator iterator() 返回一个反复器,以用它遍历集合的各元素<br>
boolean remove(Object)
*如自变量在集合里,就删除那个元素的一个实例。如果已进行了删除,就返回“真”<br>
boolean removeAll(Collection)
*删除自变量里的所有元素。如果已进行了任何删除,就返回“真”<br>
boolean retainAll(Collection)
*只保留包含在一个自变量里的元素(一个理论的“交集”)。如果已进行了任何改变,就返回“真”<br>
int size() 返回集合内的元素数量<br>
Object[] toArray() 返回包含了集合内所有元素的一个数组<br>
<br>
*这是一个“可选的”方法,有的集合可能并未实现它。若确实如此,该方法就会遇到一个UnsupportedOperatiionException,即一个“操作不支持”违例,详见第9章。<br>
<br>
下面这个例子向大家演示了所有方法。同样地,它们只对从集合继承的东西有效,一个ArrayList作为一种“不常用的分母”使用:<br>
<br>
367-369页程序<br>
<br>
通过第一个方法,我们可用测试数据填充任何集合。在当前这种情况下,只是将int转换成String。第二个方法将在本章其余的部分经常采用。<br>
newCollection()的两个版本都创建了ArrayList,用于包含不同的数据集,并将它们作为集合对象返回。所以很明显,除了Collection接口之外,不会再用到其他什么。<br>
print()方法也会在本节经常用到。由于它用一个反复器(Iterator)在一个集合内遍历,而任何集合都可以产生这样的一个反复器,所以它适用于List和Set,也适用于由一个Map生成的Collection。<br>
main()用简单的手段显示出了集合内的所有方法。<br>
在后续的小节里,我们将比较List,Set和Map的不同实现方案,同时指出在各种情况下哪一种方案应成为首选(带有星号的那个)。大家会发现这里并未包括一些传统的类,如Vector,Stack以及Hashtable等。因为不管在什么情况下,新集合内都有自己首选的类。<br>
<br>
8.7.2 使用Lists<br>
<br>
369-370页表<br>
<br>
List(接口) 顺序是List最重要的特性;它可保证元素按照规定的顺序排列。List为Collection添加了大量方法,以便我们在List中部插入和删除元素(只推荐对LinkedList这样做)。List也会生成一个ListIterator(列表反复器),利用它可在一个列表里朝两个方向遍历,同时插入和删除位于列表中部的元素(同样地,只建议对LinkedList这样做)<br>
ArrayList* 由一个数组后推得到的List。作为一个常规用途的对象容器使用,用于替换原先的Vector。允许我们快速访问元素,但在从列表中部插入和删除元素时,速度却嫌稍慢。一般只应该用ListIterator对一个ArrayList进行向前和向后遍历,不要用它删除和插入元素;与LinkedList相比,它的效率要低许多<br>
LinkedList
提供优化的顺序访问性能,同时可以高效率地在列表中部进行插入和删除操作。但在进行随机访问时,速度却相当慢,此时应换用ArrayList。也提供了addFirst(),addLast(),getFirst(),getLast(),removeFirst()以及removeLast()(未在任何接口或基础类中定义),以便将其作为一个规格、队列以及一个双向队列使用<br>
<br>
下面这个例子中的方法每个都覆盖了一组不同的行为:每个列表都能做的事情(basicTest()),通过一个反复器遍历(iterMotion())、用一个反复器改变某些东西(iterManipulation())、体验列表处理的效果(testVisual())以及只有LinkedList才能做的事情等:<br>
<br>
370-373页程序<br>
<br>
在basicTest()和iterMotiion()中,只是简单地发出调用,以便揭示出正确的语法。而且尽管捕获了返回值,但是并未使用它。在某些情况下,之所以不捕获返回值,是由于它们没有什么特别的用处。在正式使用它们前,应仔细研究一下自己的联机文档,掌握这些方法完整、正确的用法。<br>
<br>
8.7.3 使用Sets<br>
Set拥有与Collection完全相同的接口,所以和两种不同的List不同,它没有什么额外的功能。相反,Set完全就是一个Collection,只是具有不同的行为(这是实例和多形性最理想的应用:用于表达不同的行为)。在这里,一个Set只允许每个对象存在一个实例(正如大家以后会看到的那样,一个对象的“值”的构成是相当复杂的)。<br>
<br>
374页表<br>
<br>
Set(接口) 添加到Set的每个元素都必须是独一无二的;否则Set就不会添加重复的元素。添加到Set里的对象必须定义equals(),从而建立对象的唯一性。Set拥有与Collection完全相同的接口。一个Set不能保证自己可按任何特定的顺序维持自己的元素<br>
HashSet* 用于除非常小的以外的所有Set。对象也必须定义hashCode()<br>
ArraySet 由一个数组后推得到的Set。面向非常小的Set设计,特别是那些需要频繁创建和删除的。对于小Set,与HashSet相比,ArraySet创建和反复所需付出的代价都要小得多。但随着Set的增大,它的性能也会大打折扣。不需要HashCode()<br>
TreeSet 由一个“红黑树”后推得到的顺序Set(注释⑦)。这样一来,我们就可以从一个Set里提到一个顺序集合<br>
<br>
⑦:直至本书写作的时候,TreeSet仍然只是宣布,尚未正式实现。所以这里没有提供使用TreeSet的例子。<br>
<br>
下面这个例子并没有列出用一个Set能够做的全部事情,因为接口与Collection是相同的,前例已经练习过了。相反,我们要例示的重点在于使一个Set独一无二的行为:<br>
<br>
374-375页程序<br>
<br>
重复的值被添加到Set,但在打印的时候,我们会发现Set只接受每个值的一个实例。<br>
运行这个程序时,会注意到由HashSet维持的顺序与ArraySet是不同的。这是由于它们采用了不同的方法来保存元素,以便它们以后的定位。ArraySet保持着它们的顺序状态,而HashSet使用一个散列函数,这是特别为快速检索设计的)。创建自己的类型时
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -