教案课程名称黄潇《Web系统开发》授课教师教学题目教学时数3学时第3章泛型与集合1.泛型泛型类、泛型接口、泛型方法教学内容2.集合Collection、List、Set、Map集合1.知识目标:理解泛型机制和集合框架的概念和原理。理解集合框架的组成及常用集合类的使用。熟悉List接口,Set接口和Map接口的作用。2.能力目标:教学目标能独立使用Collection接口和Set接口以及Map接口。掌握迭代器的使用。培养学生的逻辑思维能力、团队协作精神和创新意识。3.思政目标:培养严谨、精益求精的大国工匠精神。培养学生的社会责任感、职业道德和团队协作精神,提升学生的综合素质。教学重点ArrayList类、LinkedList类、HashSet、HashMap类等的使用。教学难点选代器Iterator接口的使用。TreeSet类的使用。教学课型理论课授课手段多媒体教学口实验课授课方法讲授法+案例分析法+实践操作法专业术语Generics,Collection,List,Set,Map,Iterator1.梁永先、陈滢生、尹校军,JavaWeb程序设计(慕课版)第2版,人民邮电出版社,2021.3参考资料2.汪诚波,JavaWeb开发技术与实践,清华大学出版社,2018.93.千锋教育高教产品研发部,JavaWeb开发实战,清华大学出版社,2018.11实现字符出现次数的统计。课后作业具体要求:通过键盘输入一个字符串,按字母顺序打印出每个字符及其出现频率。教学后记
教 案 课程名称 《Web 系统开发》 授课教师 黄 潇 教学题目 第 3 章 泛型与集合 教学时数 3 学时 教学内容 1. 泛型 泛型类、泛型接口、泛型方法 2. 集合 Collection、List、Set、Map 集合 教学目标 1. 知识目标: 理解泛型机制和集合框架的概念和原理。 理解集合框架的组成及常用集合类的使用。 熟悉 List 接口,Set 接口和 Map 接口的作用。 2. 能力目标: 能独立使用 Collection 接口和 Set 接口以及 Map 接口。 掌握迭代器的使用。 培养学生的逻辑思维能力、团队协作精神和创新意识。 3. 思政目标: 培养严谨、精益求精的大国工匠精神。 培养学生的社会责任感、职业道德和团队协作精神,提升学生的综合素质。 教学重点 ArrayList 类、LinkedList 类、HashSet、HashMap 类等的使用。 教学难点 迭代器 Iterator 接口的使用。TreeSet 类的使用。 教学课型 理论课 实验课 授课手段 多媒体教学 授课方法 讲授法 + 案例分析法 + 实践操作法 专业术语 Generics,Collection,List,Set,Map,Iterator 参考资料 1. 梁永先、陈滢生、尹校军,Java Web 程序设计(慕课版)第 2 版,人民邮电出版社,2021.3 2. 汪诚波,Java Web 开发技术与实践, 清华大学出版社,2018.9 3. 千锋教育高教产品研发部,Java Web 开发实战,清华大学出版社,2018.11 课后作业 实现字符出现次数的统计。 具体要求:通过键盘输入一个字符串,按字母顺序打印出每个字符及其出现频率。 教学后记
复习旧课,引入新课教学设计:课前引导学生查找资料,提前了解集合在Java中的重要地位,并通过提问问题启发学生思考从而引出泛型,让学生对本讲内容的学习充满期待。一、复习旧课复习I/O流的知识点,设置提问:1.字节流和字符流的区别是,字符流用于传输(),而字节流可以传输()。2.java.io包中可以用于从文件中直接读取字符的是()类。3.字节输入流和字节输出流的抽象父类,分别是()和()。4.DatalnputStream和()是两个与平台无关的数据操作流。二、引入新课【引例】public class GenericDemolpublic staticvoid main(Stringlargs)Point pl = new Point(),pl.setX(2);int xl =pl.getX(,System.out.println(x1);37class Point(教学组织private Integer x, y,过程1publicIntegergetxO(return x)public void setX(Integer x) (this.x=x,)(10分钟)public Integer getYO (return y:)publicvoidsetY(Integery)(this.y=y:).如何Point的成员变量想换成其他类型,该怎么办?packagegenericspublicclassGenericDemoopublicstaticvoidmain(Stringllargs)PointObjectpl=newPointObject()pl.setX(2);int xl = (Integer)p1.getX(O);System.out.println(x1),PointObjectp2=newPointObjectO);p2.setX(2.2),doublex2= (Double)p2.getX()System.out.println(x2);1class PointObjectprivate Object x,y:public Object getx() returnx,!public void setX(Object x)this.x =x,1publicObjectgetYOreturn y, ?publicvoid setY(Integery)this.y=y,1
教学组织 过程 1 (10 分钟) 复习旧课,引入新课 教学设计: 课前引导学生查找资料,提前了解集合在 Java 中的重要地位,并通过提问问题启发 学生思考从而引出泛型,让学生对本讲内容的学习充满期待。 一、复习旧课 复习 I/O 流的知识点,设置提问: 1. 字节流和字符流的区别是,字符流用于传输( ),而字节流可以传输( )。 2. java.io 包中可以用于从文件中直接读取字符的是( )类。 3. 字节输入流和字节输出流的抽象父类,分别是( )和( )。 4. DataInputStream 和( )是两个与平台无关的数据操作流。 二、引入新课 【引例】 public class GenericDemo1 { public static void main(String[] args) { Point p1 = new Point(); p1.setX(2); int x1 = p1.getX(); System.out.println(x1); } } class Point{ private Integer x, y; public Integer getX() {return x;} public void setX(Integer x) {this.x = x;} public Integer getY() {return y;} public void setY(Integer y) {this.y = y;} } 如何 Point 的成员变量想换成其他类型,该怎么办? package generics; public class GenericDemo0 { public static void main(String[] args) { PointObject p1 = new PointObject(); p1.setX(2); int x1 = (Integer)p1.getX(); System.out.println(x1); PointObject p2 = new PointObject(); p2.setX(2.2); double x2 = (Double)p2.getX(); System.out.println(x2); } } class PointObject{ private Object x,y; public Object getX() { return x; } public void setX(Object x) { this.x = x; } public Object getY() { return y; } public void setY(Integer y) { this.y = y; } }
但是这样还存在些问题,比如每当使用其成员时,必须先进行强制类型转换。可以使用泛型来解决该问题。思政元素:强调编写安全、高效代码的重要性,引导学生思考作为程序员的社会责任。鼓励学生在解决问题时尝试不同的方法,培养创新意识和批判性思维。本讲主要内容教学设计:用参数的思想来介绍泛型,讲解常见的三种泛型及其使用,并使用泛型类来解决引例中存在的问题,从而加深学生对泛型的理解。3.1泛型(Generics)泛型是JDK5.0以后的新特性,它的本质是参数化类型,也就是说将所操作的数据类型指定为一个参数。这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。·3.1.1泛型类1.语法:类名<T,K...V>其中T、K、V等代表任意一种数据类型,可以是引用类型,不能是基本类型;泛型可以任意取名,但必须满足Java的命名规范,建议首字母是一个大写字母。2.【示例】使用泛型类解决引例中的问题如下:package generics;publicclassGenericDemo2(public static void main(String[]args)教学组织Entry<String,Integer>el=new Entry<>("数学",95);过程3System.out.println(e1);(15分钟)2=newEntry<>("中国""山西");Entry<String,String>e2System.out.println(e2);1class Entry<T,E>fprivate T t;private E e;public Entry(T t,E e){this.t = t;this.e = e;7@Overridepublic string tostring() (return t+":"+e;}子·3.1.2泛型接口语法:接口名<TK....V>其中T、K、V等代表任意一种数据类型,可以是引用类型,不能是基本类型;泛型可以任意取名,但必须满足Java的命名规范,建议首字母是一个大写字母。·3.1.3泛型方法1.语法:访问控制修饰符<T,K.V>返回值类型方法名(参数列表)方法体;1
但是这样还存在些问题,比如每当使用其成员时,必须先进行强制类型转换。——可 以使用泛型来解决该问题。 思政元素:强调编写安全、高效代码的重要性,引导学生思考作为程序员的社会责 任。鼓励学生在解决问题时尝试不同的方法,培养创新意识和批判性思维。 教学组织 过程 3 (15 分钟) 本讲主要内容 教学设计: 用参数的思想来介绍泛型,讲解常见的三种泛型及其使用,并使用泛型类来解决引 例中存在的问题,从而加深学生对泛型的理解。 3.1 泛型(Generics) 泛型是 JDK5.0 以后的新特性,它的本质是参数化类型,也就是说将所操作的数据类 型指定为一个参数。 这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型 方法。 3.1.1 泛型类 1. 语法:类名<T,K,.,V> 其中 T、K、V 等代表任意一种数据类型,可以是引用类型,不能是基本类型; 泛型可以任意取名,但必须满足 Java 的命名规范,建议首字母是一个大写字母。 2. 【示例】使用泛型类解决引例中的问题如下: package generics; public class GenericDemo2 { public static void main(String[] args) { Entry<String, Integer> e1 = new Entry<>("数学",95); System.out.println(e1); Entry<String, String> e2 = new Entry<>("中国","山西"); System.out.println(e2); } } class Entry<T, E>{ private T t; private E e; public Entry(T t, E e) { this.t = t; this.e = e; } @Override public String toString() { return t + ": " + e; } } 3.1.2 泛型接口 语法:接口名<T,K,.,V> 其中 T、K、V 等代表任意一种数据类型,可以是引用类型,不能是基本类型; 泛型可以任意取名,但必须满足 Java 的命名规范,建议首字母是一个大写字母。 3.1.3 泛型方法 1. 语法: 访问控制修饰符 <T,K,.,V> 返回值类型 方法名(参数列表){ 方法体; }
2.【示例】泛型方法的定义。public class GenericMethodDemo3publicstaticvoidmain(Stringlargs)Integer1=newInteger2.5.81/泛型方法的使用Integer ii=getFirstElement(i),System.out.println(ii),String[ls=newString[l"北京""上海""深圳"!1/泛型方法的使用String ss =getFirstElement(s);System.out.println(ss):2public static <T> T getFirstElement(T It)泛型方法的定义return t[0];3。3.1.4限制泛型的可用类型1.两种方法:(1)<Textends类名>表示泛型必须是指定类或者是指定类的子类。(2)<Textends接口名>表示泛型必须是指定接口或者是指定接口的实现类。2.【示例】限制泛型方法中泛型的可用类型。package generics;public class GenericMethodDemo (public static void main(stringl] args)Integer[] i= new Integer[](2,5,8];Integer ii =getFirstElement(i);System.out.println(ii);String[] s=newString[]"北京","上海","深圳"}//String ss=getFirstElement(s)//编译错误,因string并不是Number类或其子类。//System.out.println(ss);1public static <T extends Number> T getFirstElement(T[] t)(return t[o];子·3.1.5使用类型通配符1.三种:(1)类型通配符语法:<?>表示泛型可以是任意类型。(2)利用通配符指定类型的上限:语法:<?extends类名/接口名>表示泛型必须是指定类型或者是指定类的子类。(3)利用通配符指定类型的下限:语法:<?super类名/接口名>表示泛型必须是指定类型或者是指定类的父类。2.【示例】GenericwildcardDemo.java
2. 【示例】泛型方法的定义。 public class GenericMethodDemo3 { public static void main(String[ ] args) { Integer[ ] i = new Integer[ ]{2,5,8}; Integer ii = getFirstElement(i); //泛型方法的使用 System.out.println(ii); String[ ] s = new String[ ]{"北京","上海","深圳"}; String ss = getFirstElement(s); //泛型方法的使用 System.out.println(ss); } public static <T> T getFirstElement(T[ ] t){ //泛型方法的定义 return t[0]; } } 3.1.4 限制泛型的可用类型 1. 两种方法: (1)<T extends 类名> 表示泛型必须是指定类或者是指定类的子类。 (2)<T extends 接口名> 表示泛型必须是指定接口或者是指定接口的实现类。 2. 【示例】限制泛型方法中泛型的可用类型。 package generics; public class GenericMethodDemo { public static void main(String[] args) { Integer[] i = new Integer[]{2,5,8}; Integer ii = getFirstElement(i); System.out.println(ii); String[] s = new String[]{"北京","上海","深圳"}; //String ss = getFirstElement(s)//编译错误,因String并不是Number 类或其子类。 //System.out.println(ss); } public static <T extends Number> T getFirstElement(T[] t){ return t[0]; } } 3.1.5 使用类型通配符 1. 三种: (1)类型通配符 语法:<?> 表示泛型可以是任意类型。 (2)利用通配符指定类型的上限: 语法:<? extends 类名/接口名> 表示泛型必须是指定类型或者是指定类的子类。 (3)利用通配符指定类型的下限: 语法:<? super 类名/接口名> 表示泛型必须是指定类型或者是指定类的父类。 2. 【示例】 GenericWildcardDemo.java
package generics;public class GenericwildcardDemo(public static void main(stringll args)AA<object>al=new BB<object>(new Object())//AA<Object>a2=newBB<Integer>(newInteger(1));//编译错误,类型不兼容AA<?>a3=newBB<Integer>(newInteger(3));a3 =newBB<String>("test3");AA<?extends Number>a4=newBB<Integer>(newInteger(4));a4=newBB<Double>(new Double(4.4));//a4=newBB<string>("test4");//编译错误,类型不兼容AA<? super Integer>a5=new BB<Integer>(new Integer(5));//a5=newBB<Double>(newDouble(5.5));//编译错误,类型不兼容72classAA<T>T t;AA(T t)(this.t=t;)YclassBB<T>extendsAA<T>(BB(T t)(super(t);)·3.1.6泛型本质1.泛型和自动装箱拆箱一样,是编译器认可的,它的本质是Object类型,编译器在编译的时候,会自动进行类型的转换。inta=newInteger(1),/自动拆箱,等价于inta=newInteger(1).intValueO;Integerb=l;//自动装箱,等价于Integerb=Integer.valueOf(1);2.泛型使用注意事项:(1)泛型不能实例化。(2)如果AA是一个泛型类,那么,AA<Integer>与AA<Double>是一个类。(3)泛型不能表示基本类型。(4)不能对确定泛型类型使用instanceof关键字,也不能创建确定泛型类型的数组。(5)使用泛型对象时,建议给定泛型的类型,否则存在安全隐患。【示例】:package generics;public classGenericDemo3(public static void main(String[] args)(//cc<int>c1;//编译错误,因为泛型不能表示基本类型CC<0bject> c1 = new CC<>();//booleanb1=c1instanceof cc<object>//编译错误,CC<Integer>[] c2 = new cC[](];//c2newCC<Integer>[]0;CC c3=new CC();c3.t = 1;//cc<string>c4=c3;//System.out.println(c4.t)://运行时出现类型转换异常
package generics; public class GenericWildcardDemo { public static void main(String[] args) { AA<Object> a1 = new BB<Object>(new Object()); //AA<Object> a2 = new BB<Integer>(new Integer(1));//编译错误,类 型不兼容 AA<?> a3 = new BB<Integer>(new Integer(3)); a3 = new BB<String>("test3"); AA<? extends Number> a4 = new BB<Integer>(new Integer(4)); a4 = new BB<Double>(new Double(4.4)); //a4 = new BB<String>("test4");//编译错误,类型不兼容 AA<? super Integer> a5 = new BB<Integer>(new Integer(5)); //a5 = new BB<Double>(new Double(5.5));//编译错误,类型不兼容 } } class AA<T>{ T t; AA(T t){ this.t=t; } } class BB<T> extends AA<T>{ BB(T t){ super(t); } } 3.1.6 泛型本质 1. 泛型和自动装箱拆箱一样,是编译器认可的,它的本质是 Object 类型,编译器在编译的 时候,会自动进行类型的转换。 int a = new Integer(1); //自动拆箱,等价于 int a = new Integer(1).intValue(); Integer b = 1; //自动装箱,等价于 Integer b = Integer.valueOf(1); 2. 泛型使用注意事项: (1) 泛型不能实例化。 (2) 如果 AA 是一个泛型类,那么,AA<Integer>与 AA<Double>是一个类。 (3) 泛型不能表示基本类型。 (4) 不能对确定泛型类型使用 instanceof 关键字,也不能创建确定泛型类型的数组。 (5) 使用泛型对象时,建议给定泛型的类型,否则存在安全隐患。 【示例】: package generics; public class GenericDemo3 { public static void main(String[] args) { //CC<int> c1;//编译错误,因为泛型不能表示基本类型 CC<Object> c1 = new CC<>(); //boolean b1 = c1 instanceof CC<Object>;//编译错误, CC<Integer>[] c2 = new CC[]{}; //c2 = new CC<Integer>[]{}; CC c3 = new CC(); c3.t = 1; //CC<String> c4 = c3; //System.out.println(c4.t); //运行时出现类型转换异常