java 集合与泛型.docx
- 文档编号:10032140
- 上传时间:2023-02-08
- 格式:DOCX
- 页数:54
- 大小:89.90KB
java 集合与泛型.docx
《java 集合与泛型.docx》由会员分享,可在线阅读,更多相关《java 集合与泛型.docx(54页珍藏版)》请在冰豆网上搜索。
java集合与泛型
Collection接口及实现类
Java语言的Collection接口及实现类是在java.util包中定义的,其中定义了多个接口和类,它们统称为Java集合框架(JavaCollectionFramework)。
Java集合框架由两种类型构成,一个是Collection,另一个是Map。
Collection对象用于存放一组对象,Map对象用于存放一组关键字/值的对象。
Collection和Map是最基本的接口,它们又有子接口,这些接口的层次关系如图1所示。
图1Java集合框架的接口继承关系
1.1Collection接口及操作
Collection接口是所有集合类型的根接口,它有三个子接口:
Set接口、List接口和Queue接口。
Collection接口的定义如下:
publicinterfaceCollection
//基本操作
intsize();
booleanisEmpty();
booleancontains(Objectelement);
booleanadd(Eelement);
booleanremove(Objectelement);
Iteratoriterator();
//批量操作
booleancontainsAll(Collection
>c);
booleanaddAll(Collection
extendsE>c);
booleanremoveAll(Collection
>c);
booleanretainAll(Collection
>c);
voidclear();
//数组操作
Object[]toArray();
}
说明从JDK1.5开始,Java开始支持范型(generics)的概念。
在Collection接口的声明中,
这样,当我们声明一个Collection实例时,应该使用这种方式指明包含在集合中的对象类型。
这可以使编译器在编译时检查存入集合的对象类型是否正确,从而减少运行时错误。
Collection接口中定义的方法主要包括三类:
集合操作、批量操作和数组操作。
1.基本操作
实现基本操作的方法有size(),它返回集合中元素的个数;isEmpty()方法返回集合是否为空;contains()方法返回集合中是否包含指定的对象;add()方法和remove()方法实现向集合中添加元素和删除元素的功能;iterator()方法用来返回Iterator对象。
通过基本操作可以检索集合中的元素。
检索集合中的元素有两种方法:
使用增强的for循环和使用Iterator迭代对象。
(1)使用增强的for循环
使用增强的for循环不但可以遍历数组的每个元素,还可以遍历集合的每个元素。
下面的代码打印集合的每个元素:
for(Objecto:
collection)
System.out.println(o);
(2)使用迭代器
迭代器是一个可以遍历集合中每个元素的对象。
通过调用集合对象的iterator()方法可以得到Iterator对象,再调用Iterator对象的方法就可以遍历集合中的每个元素。
Iterator接口的定义如下:
publicinterfaceIterator
booleanhasNext();
Enext();
voidremove();
}
该接口的hasNext()方法返回迭代器中是否还有对象;next()方法返回迭代器中下一个对象;remove()方法删除迭代器中的对象,该方法同时从集合中删除对象。
假设c为一个Collection对象,要访问c中的每个元素,可以按下列方法实现:
Iteratorit=c.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
2.批量操作
实现批量操作的方法有containsAll(),它返回集合中是否包含指定集合中的所有元素;addAll()方法和removeAll()方法将指定集合中的元素添加到集合中和从集合中删除指定的集合元素;retainAll()方法删除集合中不属于指定集合中的元素;clear()方法删除集合中所有元素。
3.数组操作
toArray()方法可以实现集合与数组的转换。
该方法可以实现将集合元素转换成数组元素。
无参数的toArray()方法实现将集合转换成Object类型的数组。
有参数的toArray()方法将集合转换成指定类型的对象数组。
例如,假设c是一个Collection对象,下面的代码将c中的对象转换成一个新的Object数组,数组的长度与集合c中的元素个数相同。
Object[]a=c.toArray();
假设我们知道c中只包含String对象,可以使用下面代码将其转换成String数组,它的长度与c中元素个数相同:
String[]a=c.toArray(newString[0]);
1.2Set接口及实现类
Set接口是Collection的子接口,Set接口对象类似于数学上的集合概念,其中不允许有重复的元素。
Set接口没有定义新的方法,只包含从Collection接口继承的方法。
Set接口有几个常用的实现类,它们的层次关系如图2所示:
图2Set接口及实现类的层次结构
Set接口的常用的实现类有:
HashSet类、TreeSet类和LinkedHashSet类。
1.HashSet类与LinkedHashSet类
HashSet类是抽象类AbstractSet的子类,它实现了Set接口,HashSet使用哈希方法存储元素,具有最好的性能,但元素没有顺序。
HashSet类的构造方法有:
∙HashSet()创建一个空的哈希集合,装填因子(loadfactor)是0.75。
∙HashSet(Collectionc)用指定的集合c的元素创建一个哈希集合。
∙HashSet(intinitialCapacity)创建一个哈希集合,并指定的集合初始容量。
∙HashSet(intinitialCapacity,floatloadFactor)创建一个哈希集合,并指定的集合初始容量和装填因子。
LinkedHashSet类是HashSet类的子类。
该实现与HashSet的不同之处是它对所有元素维护一个双向链表,该链表定义了元素的迭代顺序,这个顺序是元素插入集合的顺序。
下面的程序从命令行输入若干英文单词,输出每个重复的单词,不同单词的个数及消除重复单词后的列表。
程序FindDups.java
importjava.util.*;
publicclassFindDups{
publicstaticvoidmain(Stringargs[]){
Set
for(Stringa:
args)
if(!
hs.add(a))
System.out.println("Duplicate:
"+a);
System.out.println(hs.size()+"distinctwords:
"+hs);
}
}
_____________________________________________________________________________▃
如果使用下面命令运行程序:
C:
\>javaFindDupsicameisawileft
会得到下面结果:
Duplicate:
i
Duplicate:
i
4distinctwords:
[i,left,saw,came]
由于上面程序中使用的实现类为HashSet,它并不保证集合中元素的顺序。
注意该程序对集合的声明中使用了泛型的方法,即加上了
Note:
D:
\java\FindDups.javausesuncheckedorunsafeoperations.
Note:
Recompilewith-Xlint:
uncheckedfordetails.
该提示说明程序中使用了未检查的或不安全的操作,如果要知道详细细节,可以带-Xlint:
unchecked参数重新编译该程序。
2.用集合对象实现集合运算
对于Set对象的批量操作方法,可以实现标准集合代数运算。
假设s1和s2是Set对象,下面的操作可实现相关的集合运算。
s1.containAll(s2):
如果s2是s1的子集,该方法返回true;
s1.addAll(s2):
实现集合s1与s2的并运算;
s1.retainAll(s2):
实现集合s1与s2的交运算;
s1.removeAll(s2):
实现集合s1与s2的差运算。
为了计算两个集合的并、交、差运算而又不破坏原来的集合,可以通过下面代码实现:
Set
union.addAll(s2);
Set
intersection.retainAll(s2);
Set
difference.removeAll(s2);
下面的程序实现了两个集合的并、交、差运算:
程序SetDemo.java
importjava.util.*;
publicclassSetDemo{
publicstaticvoidmain(Stringargs[]){
Set
Set
s1.add(newString("one"));
s1.add(newString("two"));
s1.add(newString("three"));
s2.add(newString("two"));
s2.add(newString("three"));
s2.add(newString("four"));
Set
union.addAll(s2);
Set
intersection.retainAll(s2);
Set
difference.removeAll(s2);
System.out.println(union);
System.out.println(intersection);
System.out.println(difference);
}
}
_____________________________________________________________________________▃
程序输出结果为:
[one,two,foue,three]
[two,three]
[one]
3.SortedSet接口与TreeSet类
SortedSet接口对象是有序对象的集合,其中的元素排序规则按照元素的自然顺序排列。
为了能够使元素排序,要求插入到SortedSet对象中的元素必须是相互可以比较的。
关于对象的顺序在下节讨论。
SortedSet接口中定义了下面几个方法:
∙Efirst()返回有序集合中的第一个元素。
∙Elast()返回有序集合中最后一个元素。
∙SortedSet
∙SortedSet
∙SortedSet
∙Comparator
SuperE>comparator()返回与该有序集合相关的比较器,如果集合使用自然顺序则返回null。
TreeSet是SortedSet接口的实现类,它使用红黑树为存储元素排序,它基于元素的值对元素排序,它的操作要比HashSet慢。
TreeSet类的构造方法有:
∙TreeSet()创建一个空的树集合。
∙TreeSet(Collectionc)用指定集合c中的元素创建一个新的树集合,集合中的元素是按照元素的自然顺序排序。
∙TreeSet(Comparatorc)创建一个空的树集合,元素的排序规则按给定的c的规则排序。
∙TreeSet(SortedSets)用SortedSet对象s中的元素创建一个树集合,排序规则与s的排序规则相同。
下面的程序创建一个TreeSet对象,其中添加了四个字符串对象。
从输出结果中我们可以看到,这些字符串是按照字母的顺序排列的。
程序TreeSetTest.java
importjava.util.*;
publicclassTreeSetTest{
publicstaticvoidmain(Stringargs[]){
Set
String[]s=newString[]{"one","two","three","four"};
for(inti=0;i ts.add(s[i]); System.out.println(ts); } } _____________________________________________________________________________▃ 程序输出结果为: [four,one,three,two] 1.3对象顺序 在上一小节中我们看到,在创建TreeSet类对象时如果没有指定比较器(Comparator)对象,集合中的元素是按自然顺序排列的,如果指定了比较器对象,集合中的元素是根据比较器的规则排序。 所谓自然顺序(naturalordering)指的是集合中对象的类实现了Comparable接口,并实现了其中的compareTo()方法,对象则根据该方法排序。 如果希望集合中元素能够排序,必须使元素是可比较的,即要求元素所属的类必须实现Comparable接口。 如果试图对没有实现Comparable接口的集合元素排序,将抛出ClassCastException运行时异常。 Java平台中有些类实现了Comparable接口,如基本数据类型包装类(Byte、Short、Integer、Long、Float、Double、Character、Boolean),另外还有File类、String类、Date类、BigInteger类、BigDecimal类等也实现了Comparable接口,这些类的对象直接可按自然顺序排序。 另一种排序方法是创建TreeSet对象时指定一个比较器对象,这样集合中的元素将按比较器的规则排序。 下面分别叙述这两种方法: 1.实现Comparable接口 如果要对我们自己定义的类进行排序,则应该在定义类的时候实现java.lang.Comparable接口,并实现其中的compareTo()方法,该接口的定义如下: publicinterfaceComparable publicintcompareTo(Tobj); } 该接口中只声明了一个compareTo()方法,该方法用来实现调用对象与参数对象比较,返回值是一个整数。 当调用对象小于、等于、大于参数对象时,该方法分别返回负整数、0和正整数。 下面的程序说明了如何通过实现Comparable接口对Student类的对象根据学号(id的值)进行排序。 程序Student.java importjava.util.*; publicclassStudentimplementsComparable intid; Stringname; publicStudent(intid,Stringname){ this.id=id; this.name=name; } publicintcompareTo(Students){ if(this.id return-1; elseif(this.id>s.id) return1; else return0; } publicStringtoString(){ return"{"+this.id+","+this.name+"}"; } publicstaticvoidmain(Stringargs[]){ Student[]stud=newStudent[]{ newStudent(1002,"Wang"), newStudent(1003,"Zhang"), newStudent(1001,"Zhou")}; Set for(inti=0;i ts.add(stud[i]); System.out.println(ts); } } _____________________________________________________________________________▃ 程序运行结果为: [{1001,Zhou},{1002,Wang},{1003,Zhang}] Student类实现了Comparable接口的compareTo()方法,它是根据学号(id的值)来比较两个Student对象的大小。 当将Student对象存放到TreeSet中时就是按照compareTo()方法对Student对象排序的。 2.比较器Comparator 如果一个类没有实现Comparable接口或实现了Comparable接口,我们又想改变比较规则,可以定义一个实现java.util.Comparator接口的类,然后为集合提供一个新的比较器。 Comparator接口定义了2个方法,它的声明如下: publicinterfaceComparator intcompare(Tobj1,Tobj2); booleanequals(Objectobj); } compare()方法用来比较它的两个参数。 当第一个参数小于、等于、大于第二个参数时,该方法分别返回负整数、0、正整数。 equals()方法用来比较两个Comparator对象是否相等。 字符串的默认比较规则是按字典顺序比较,假如按反顺序比较,我们可以通过下面的类来实现: 程序DescSort.java importjava.util.*; publicclassDescSortimplementsComparator publicintcompare(Strings1,Strings2){ if(pareTo(s2)>0) return-1; elseif(pareTo(s2)<0) return1; elsereturn0; } } _____________________________________________________________________________▃ 下面的程序就可以实现字符串的降序排序: 程序DescSortDemo.java importjava.util.*; publicclassDescSortDemo{ publicstaticvoidmain(Stringargs[]){ String[]s=newString[]{"China", "England","France","America","Russia",}; Set for(inti=0;i ts.add(s[i]); System.out.println(ts); Comparator ts=newTreeSet for(inti=0;i ts.add(s[i]); System.out.println(ts); } } _____________________________________________________________________________▃ 输出结果为: [America,China,England,French,Russia] [Russia,French,England,China,America] 输出的第一行是按字符串自然顺序的比较输出,第二行的输出使用了自定义的比较器,按与自然顺序相反的顺序输出。 1.4List接口及实现类 List接口也是Collection接口的子接口,它实现一种顺序表的数据结构,有时也称为序列。 存放在 List中的所有元素都有一个下标(下标从0开始),可以通过下标访问List中的元素。 List中可以包含重复元素。 List接口及其实现类的层次结构如图.3所示: 图.3List接口及实现类的层次结构 Java平台提供了两个List类的通用实现类,ArrayList类和LinkedList类。 另外,Java早期版本的Vector类和Stack类被重新修改以适应新的集合框架。 下面首先讨论List接口的操作,后面讨论这些实现类。 List接口除了继承Collection的方法外,还定义了一些自己的方法。 使用这些方法可以实现定位访问、查
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- java 集合与泛型 集合