《Java程序设计教程》课件第十章:泛型与集合.pptx
- 【下载声明】
1. 本站全部试题类文档,若标题没写含答案,则无答案;标题注明含答案的文档,主观题也可能无答案。请谨慎下单,一旦售出,不予退换。
2. 本站全部PPT文档均不含视频和音频,PPT中出现的音频或视频标识(或文字)仅表示流程,实际无音频或视频文件。请谨慎下单,一旦售出,不予退换。
3. 本页资料《《Java程序设计教程》课件第十章:泛型与集合.pptx》由用户(momomo)主动上传,其收益全归该用户。163文库仅提供信息存储空间,仅对该用户上传内容的表现方式做保护处理,对上传内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知163文库(点击联系客服),我们立即给予删除!
4. 请根据预览情况,自愿下载本文。本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
5. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007及以上版本和PDF阅读器,压缩文件请下载最新的WinRAR软件解压。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Java程序设计教程 Java 程序设计 教程 课件 第十 集合
- 资源描述:
-
1、本章学习目标:理解泛型的概念 掌握泛型类的创建和使用 理解泛型的有界类型和通配符的使用,了解泛型的限制 理解Java集合框架的结构、迭代器接口 掌握常用接口及实现类的使用 了解集合转换第十章第十章 泛型与集合泛型与集合第第1 1节节part泛型 从JDK 5.0开始,Java引入“参数化类型(parameterized type)”的概念,这种参数化类型称为“泛型(Generic)”。泛型是将数据类型参数化,即在编写代码时将数据类型定义成参数,这些类型参数在使用之前再进行指明。泛型提高了代码的重用性,使得程序更加灵活、安全和简洁。泛型本节概述 在JDK 5.0之前,为了实现参数类型的任意化,都
2、是通过Object类型来处理。但这种处理方式所带来的缺点是需要进行强制类型转换,此种强制类型转换不仅使代码臃肿,而且要求程序员必须对实际所使用的参数类型已知的情况下才能进行,否则容易引起ClassCastException异常。从JDK 5.0开始,Java增加对泛型的支持。使用泛型之后就不会出现上述问题。泛型的好处是在程序编译期会对类型进行检查,捕捉类型不匹配错误,以免引起ClassCastException异常;而且泛型不需要进行强制转换,数据类型都是自动转换的。泛型经常使用在类、接口和方法的定义中,分别称为泛型类、泛型接口和泛型方法。泛型类是引用类型,在内存堆中。10.1.1泛型定义泛型
3、定义定义泛型类的语法格式如下:访问符 class 类名 /类体.其中:(1)尖括号中是类型参数列表,可以由多个类型参数组成,多个类型参数之间使用“,”隔开。(2)类型参数只是占位符,一般使用大写的“T”、“U”、“V”等作为类型参数。下述代码示例了泛型类的定义,代码如下所示。class Node private T data;public Node next;/省略.10.1.1泛型定义泛型定义 从Java 7开始,实例化泛型类时只需给出一对尖括号“”即可,Java可以推断尖括号中的泛型信息。将两个尖括号放在一起像一个菱形,因此也被称为“菱形”语法。Java 7“菱形”语法实例化泛型类的格式如
4、下:类名 对象=new 类名(构造方法参数列表);例如:Node myNode=new Node();下述代码示例了一个泛型类的定义,代码如下所示。10.1.1泛型定义【代码10.1】Generic.javapackage com;public class Generic private T data;public Generic()public Generic(T data)this.data=data;public T getData()return data;public void setData(T data)this.data=data;public void showDataTyp
5、e()System.out.println(数据的类型是:+data.getClass().getName();10.1.1泛型定义 上述代码定义了一个名为Generic的泛型类,并提供两个构造方法。私有属性data的数据类型采用泛型,可以在使用时在进行指定。showDataType()方法显示data属性的具体类型名称,其中“getClass().getName()”用于获取对象的类名。下述代码示例了泛型类的实例化,并访问相应方法,代码如下所示。【代码10.2】GenericExample.javapackage com;public class GenericExample public
6、static void main(String args)Generic str=new Generic(字符串类型泛型类!);str.showDataType();System.out.println(str.getData();System.out.println(-);/定义泛型类的一个Double版本 Generic dou=new Generic(3.1415);dou.showDataType();System.out.println(dou.getData();10.1.1泛型定义 上述代码使用Generic泛型类,并分别实例化为String和Double两种不同类型的对象。程序
7、运行结果如下:数据的类型是:java.lang.String 欢迎使用泛型类!-数据的类型是:java.lang.Double 3.141510.1.2通配符通配符当使用一个泛型类时(包括声明泛型变量和创建泛型实例对象),都应该为此泛型类传入一个实参,否则编译器会提出泛型警告。假设现在定义一个方法,该方法的参数需要使用泛型,但类型参数是不确定的,此时如果考虑使用Object类型来解决,编译时则会出现错误。以之前定义的泛型类Generic为例,考虑如下代码:【代码10.3】NoWildcardExample.javapackage com;public class NoWildcardExamp
8、le public static void myMethod(Generic g)g.showDataType();public static void main(String args)/参数类型是ObjectGeneric gstr=new Generic(Object);myMethod(gstr);/参数类型是IntegerGeneric gint=new Generic(12);/这里将产生一个错误myMethod(gint);/参数类型是IntegerGeneric gdou=new Generic(12.0);/这里将产生一个错误myMethod(gdou);10.1.2通配符
9、上述代码中定义的myMethod()方法的参数是泛型类Generic,该方法的意图是能够处理各种类型参数,但在使用Generic类时必须指定具体的类型参数,此处在不使用通配符的情况下,只能使用“Generic”的方式。这种方式将造成main()方法中的语句编译时产生类型不匹配的错误,程序无法运行。程序中出现的这个问题,可以使用通配符解决。通配符是由“?”来表示一个未知类型,从而解决类型被限制、不能动态根据实例进行确定的缺点。下述代码使用通配符“?”重新实现上述处理过程,实现处理各种类型参数的情况,代码如下所示。10.1.2通配符【代码10.4】UseWildcardExample.javapa
10、ckage com;public class UseWildcardExample public static void myMethod(Generic g)g.showDataType();public static void main(String args)/参数类型是StringGeneric gstr=new Generic(Object);myMethod(gstr);/参数类型是IntegerGeneric gint=new Generic(12);myMethod(gint);/参数类型是IntegerGeneric gdou=new Generic(12.0);myMeth
11、od(gdou);10.1.2通配符 上述代码定义了myMethod()方法时,使用“Generic”通配符的方式作为类型参数,如此便能够处理各种类型参数,且程序编译无误,能够正常运行。程序运行结果如下:数据的类型是:java.lang.String 数据的类型是:java.lang.Integer 数据的类型是:java.lang.Double有界类型有界类型 泛型的类型参数可以是各种类型,但有时候需要对类型参数的取值进行一定程度的限制,以便类型参数在指定范围内。针对这种情况,Java提供了“有界类型”,来限制类型参数的取值范围。有界类型分两种:(1)使用extends关键字声明类型参数的上
12、界。(2)使用super关键字声明类型参数的下界。10.1.3有界类型有界类型1.1.上界上界 使用extends关键字可以指定类型参数的上界,限制此类型参数必须继承自指定的父类或父类本身。被指定的父类则称为类型参数的“上界(upper bound)”。类型参数的上界可以在定义泛型时进行指定,也可以在使用泛型时进行指定,其语法格式分别如下:/定义泛型时指定类型参数的上界 访问符 class 类名/类体./使用泛型时指定类型参数的上界 泛型类 例如:/定义泛型时指定类型参数的上界 public class Generic/类体./使用泛型时指定类型参数的上界 Generic 上述代码限制了泛型类
13、Generic的类型参数必须是Number类及其子类,因此可以将Number类称为此类型参数的上界。Java中Number类是一个抽象类,所有数值类都继承此抽象类,即Integer、Long、Float、Double等用于数值操作的类都继承Number类。10.1.3有界类型下述代码示例了使用类型参数的上界,代码如下所示。【代码10.5】UpBoundGenericExample.javapackage com;class UpBoundGeneric private T data;public UpBoundGeneric()public UpBoundGeneric(T data)this
14、.data=data;public T getData()return data;public void setData(T data)this.data=data;public void showDataType()System.out.println(数据的类型是:+data.getClass().getName();10.1.3有界类型public class UpBoundGenericExample/使用泛型Generic时指定其类型参数的上界public static void myMethod(Generic g)g.showDataType();public static vo
15、id main(String args)/参数类型是IntegerGeneric gint=new Generic(1);myMethod(gint);/参数类型是LongGeneric glong=new Generic(10L);myMethod(glong);/参数类型是StringGeneric gstr=new Generic(String);/产生错误/myMethod(gstr);10.1.3有界类型/使用已经限定参数的泛型UpBoundGenericUpBoundGeneric ubgint=new UpBoundGeneric(20);ubgint.showDataType(
16、);UpBoundGeneric ubglon=new UpBoundGeneric(20L);ubglon.showDataType();/产生错误/UpBoundGeneric ubgstr=new UpBoundGeneric(指定上界);10.1.3有界类型 上述代码中定义了一个泛型类UpBoundGeneric,并指定其类型参数的上界是Number类。在定义myMethod()方法时指定泛型类Generic的类型参数的上界也是Number类。在main()方法中进行使用时,当类型参数不是Number的子类时都会产生错误。因UpBoundGeneric类在定义时就已经限定了类型参数的上
17、界,所以出现“UpBoundGeneric”就会报错。Generic类在定义时并没有上界限定,而是在定义myMethod()方法使用Generic类才进行限定的,因此出现“Generic”不会报错,调用“myMethod(gstr)”时才会报错。程序运行结果如下所示:数据的类型是:java.lang.Integer 数据的类型是:java.lang.Long 数据的类型是:java.lang.Integer 数据的类型是:java.lang.Long2.2.下界下界 使用super关键字可以指定类型参数的下界,限制此类型参数必须是指定的类型本身或其父类,直至Object类。被指定的类则称为类型
18、参数的“下界(lower bound)”。类型参数的下界通常在使用泛型时进行指定,其语法格式如下所示:泛型类 例如:Generic 上述代码限制了泛型类Generic的类型参数必须是String类本身或其父类Object,因此可以将String类称为此类型参数的下界。下述代码示例泛型类型参数下界的声明和使用,代码如下所示。10.1.3有界类型【代码10.6】LowBoundGenericExample.javapackage com;public class LowBoundGenericExample/使用泛型Generic时指定其类型参数的下界public static void myMe
19、thod(Generic g)g.showDataType();public static void main(String args)/参数类型是StringGeneric gstr=new Generic(String类本身);myMethod(gstr);/参数类型是ObjectGeneric gobj=new Generic(10);myMethod(gobj);/参数类型是IntegerGeneric gint=new Generic(10);/产生错误/myMethod(gint);10.1.3有界类型 上述代码在定义myMethod()方法时指定泛型类Generic的类型参数的上
20、界是String类,因此在main()方法中进行使用时,当参数类型不是String类或其父类Object时,都会产生错误。程序运行结果如下:数据的类型是:java.lang.String 数据的类型是:java.lang.Integer 泛型中使用extends关键字限制类型参数必须是指定的类本身或其子类,而super关键字限制类型参数必须是指定的类本身或其父类。在泛型中经常使用extends关键字指定上界,而很少使用super关键字指定下界。10.1.3有界类型 Java语言没有真正实现泛型。Java程序在编译时生成的字节码中是不包含泛型信息的,泛型的类型信息将在编译处理时被擦除掉,这个过程
21、称为类型擦除。这种实现理念造成Java泛型本身有很多漏洞,虽然Java 8对类型推断进行了改进,但依然需要对泛型的使用上做一些限制,其中大多数限制都是由类型擦除和转换引起的。Java对泛型的限制如下:(1)泛型的类型参数只能是类类型(包括自定义类),不能是简单类型。(2)同一个泛型类可以有多个版本(不同参数类型),不同版本的泛型类的实例是不兼容的,例如:“Generic”与“Generic”的实例是不兼容的。(3)定义泛型时,类型参数只是占位符,不能直接实例化,例如:“new T()”是错误的。(4)不能实例化泛型数组,除非是无上界的类型通配符,例如:“Generic a=new Generi
22、c 10”是错误的,而“Generic a=new Generic 10”是被允许的。(5)泛型类不能继承Throwable及其子类,即泛型类不能是异常类,不能抛出也不能捕获泛型类的异常对象,例如:“class GenericException extends Exception”、“catch(T e)”都是错误的。10.1.4泛型的限制泛型的限制第第2 2节节part集合概述 Java的集合类是一些常用的数据结构,例如:队列、栈、链表等。Java集合就像一种“容器”,用于存储数量不等的对象,并按照规范实现一些常用的操作和算法。程序员在使用Java的集合类时,不必考虑数据结构和算法的具体实现
23、细节,根据需要直接使用这些集合类并调用相应的方法即可,从而提高了开发效率。集合概述本节概述10.2.1集合框架 在JDK 5.0之前,Java集合会丢失容器中所有对象的数据类型,将所有对象都当成Object类型进行处理。从JDK 5.0增加泛型之后,Java集合完全支持泛型,可以记住容器中对象的数据类型,从而可以编写更简洁、健壮的代码。Java所有的集合类都在java.util包下,从JDK 5.0开始为了处理多线程环境下的并发安全问题,又在java.util.concurrent包下提供了一些多线程支持的集合类。Java的集合类主要由两个接口派生而出:Collection和Map,这两个接口
24、派生出一些子接口或实现类。Collection和Map是集合框架的根接口,如图10.1所示是Collection集合体系的继承树。集合框架10.2.1集合框架Collection接口下有3个子接口:(1)Set接口:无序、不可重复的集合;(2)Queue接口:队列集合;(3)List接口:有序、可以重复的集合。10.2.1集合框架 如图10.2所示是Map集合体系的继承树。所有Map的实现类用于保存具有映射关系的数据,即Map保存的每项数据都是由key-value键值对组成。Map中的key用于标识集合中的每项数据,是不可重复的,可以通过key来获取Map集合中的数据项。10.2.1集合框架
25、Java中的集合分为三大类:(1)Set集合:将一个对象添加到Set集合时,Set集合无法记住添加的顺序,因此Set集合中的元素不能重复,否则系统无法识别该元素,访问Set集合中的元素也只能根据元素本身进行访问;(2)List集合:与数组类似,List集合可以记住每次添加元素的顺序,因此可以根据元素的索引访问List集合中的元素,List集合中的元素可以重复且长度是可变的;(3)Map集合:每个元素都是有key/value键值对组成,可以根据每个元素的key来访问对应的value,Map集合中的key不允许重复,value可以重复。本章主要介绍常用的集合接口及其实现类,例如List、Set、M
展开阅读全文