2java高级集合部分讲课教案.docx
- 文档编号:27972603
- 上传时间:2023-07-07
- 格式:DOCX
- 页数:22
- 大小:110.17KB
2java高级集合部分讲课教案.docx
《2java高级集合部分讲课教案.docx》由会员分享,可在线阅读,更多相关《2java高级集合部分讲课教案.docx(22页珍藏版)》请在冰豆网上搜索。
2java高级集合部分讲课教案
2.java高级集合部分
集合框架
KeyPoint
* Collection接口、Set接口、List接口基本操作:
一)集合框架:
Java语言的设计者对常用的数据结构和算法做了一些规范(接口)和实现(实现接口的类)。
所有抽象出来的数据结构和操作(算法)统称为集合框架。
三)集合框架的接口(规范)
Collection接口:
存储一组不唯一,无序的对象
List接口:
存储一组不唯一,有序的对象
Set接口:
存储一组唯一,无序的对象
Map接口:
存储一组键值对象,提高键(key)到值(value)的映射
(四)各种接口的实现类:
List接口的2个常用实现类:
ArrayList和LinkedList
ArrayList类:
在它的底层代码中,实际是有一个Object型数组,通过一些方法实现数组的扩容,数组本身长度是在定义的时候就不能改变,JDK的源码底层就是通过新创建一个数组,长度比原来的长,把之前原数组的每个元素复制过来,然后把新数组的首地址赋值给了原数组的引用,就这样实现了可变长度数组;所以ArrayList的特点就是:
遍历和随机访问的速度快,插入对象和删除对象的效率就低,因为底层的实现是通过数组来实现
LinkedList类:
底层通过结点来实现的,它有2个Node结点属性,一个根结点first,一个尾结点last。
添加的元素是保存在Node结点属性中item,看下面JDK源码,然后通过Node还有2个属性next和prev分别指向后一个保存元素的结点和指向前一个保存元素的结点;就这样形成一条逻辑上的一条链,它们在堆内存中内存是不连续的;所以LinkedList类的特点:
访问元素的效率不高,但是插入和删除元素的效率高,因为通过结点改变指向就可以实现了。
HashMap底层就是通过结点数组(数组+结点)来实现的,为什么put()方法存key和value的时候,key不能重复,重复的话value会覆盖原先的value,key值在底层是通过它的hashCode来保证唯一性
同样的来讲解一下HashSet,给大家看看一个它的JDK源码,map是HashMap类型,把数据存储到map的key中,所以说HashSet存储的元素是不能重复的
*List接口及其实现类:
List接口及其实现类:
特点:
其元素以线性方式存储;
元素可重复;
元素有序;
可以对元素的位置精确控制;
实现类:
ArrayList
LinkedList
Vector
Stack
List接口常用的方法:
booleanadd(Ee):
向列表尾部添加指定的元素;
voidadd(intindex,Eelement):
在列表指定位置插入指定元素;
booleanaddAll(Collectionc):
添加指定的collection中的所有元素到此列表的结尾;
booleanaddAll(intindex,Collectionc):
将指定的collection中的所有元素插入到列表中的指定位置;
设置元素:
Eset(intindex,Eelement):
用指定的元素替换列表中的指定位置的元素
获取元素:
Eget(intindex):
返回列表中指定位置的元素;
intindexOf(Objecto):
返回此列表中第一次出现的指定元素的索引,否则返回-1;
intlastIndexOf(Objecto):
返回次列表中最后出现的指定元素的索引,否则返回-1;
List
返回列表中指定的fromIndex(包括)和toIndex(不包括)之间的子列表;
移除元素:
Eremove(intindex):
移除列表中指定位置的元素;
booleanremove(Objecto):
从此列表中移除第一次出现的指定的元素(如果存在);
voidclear():
从列表中移除所有元素;
相关判断方法:
booleancontains(Objecto):
如果列表包含指定的元素,则返回true;
booleancontaionsAll(Coollectionc):
如果列表包含指定collection的所有元素,则返回true;
booleanequals(Objecto):
比较指定的对象与列表是否相等;
booleanisEmpty():
如果列表不包含元素,则返回true;
*Set接口及其实现类:
1.Set接口
Set是对数学上集的抽象,Set中不包含重复的元素.如何界定是否是重复元素?
Set最多可含一个null元素;对于任意的非null元素e1和e2,都满足e1.equals(e2)==false.
Object.hashcode()的约定:
a.在程序的一次执行中,无论何时在同一个java对象上重复调用hashcode(),都必须一致地返回同一个整数值,并不像Object.equals()那样提供Object是否被修改了的信息,但这个整数值不必在同一个应用程序的多次运行之间保持一致.
b.如果两个Object通过equals()判断是相等的,那么,在这两个Object上调用hashcode()必返回相同的值.
c.如果两个Object通过equals()判断是不相等的,那么,并不要求这两个Object.hashcode()返回不同的整数值.
2.Set实现
HashSet是使用一个哈希表存储元素的,是非排序的,可以随机访问,是Set的最优性能实现.TreeSet实现了SortedSet接口,使用一个红黑树来存储元素,提供了元素的有序存储和访问.
2.1HashSet
HashSet在底层实现上依赖于HashMap.
2.2TreeSet
Set接口有一个子接口:
SortedSet,提供了集合元素的顺序存储,其中元素保持升序排列.为了在加入一个元素到SortedSet实现时能对这些元素排序,元素类型必须实现Comarable接口,或者建立SortedSet时使用Comparator.否则程序在运行时将抛出ClassCastException.
3.使用Set的注意事项
如果Set中存储了可变对象,当这些对象出现重复元素,从而从根本上违反了Set的约定,Set的行为也变得不确定.所以,在Set中存储可变对象时,一定要十分小心.同样,对于Map中的key也一样,因为Map中的key也是不允许重复的.
*迭代遍历
*Comparable接口:
1.什么是Comparable接口
此接口强行对实现它的每个类的对象进行整体排序。
此排序被称为该类的自然排序 ,类的 compareTo 方法被称为它的自然比较方法 。
实现此接口的对象列表(和数组)可以通过 Collections.sort (和 Arrays.sort )进行自动排序。
实现此接口的对象可以用作有序映射表中的键或有序集合中的元素,无需指定比较器。
强烈推荐(虽然不是必需的)使自然排序与equals一致。
所谓与equals一致是指对于类 C 的每一个 e1 和 e2 来说,当且仅当 (pareTo((Object)e2)==0) 与e1.equals((Object)e2) 具有相同的布尔值时,类 C 的自然排序才叫做与equals一致 。
2.实现什么方法
intcompareTo(To)
比较此对象与指定对象的顺序。
如果该对象小于、等于或大于指定对象,则分别返回负整数、零或正整数。
强烈推荐(pareTo(y)==0)==(x.equals(y))这种做法,但不是严格要求这样做。
一般来说,任何实现Comparable接口和违背此条件的类都应该清楚地指出这一事实。
推荐如此阐述:
“注意:
此类具有与equals不一致的自然排序。
”
参数:
o-要比较的对象。
返回:
负整数、零或正整数,根据此对象是小于、等于还是大于指定对象。
抛出:
ClassCastException-如果指定对象的类型不允许它与此对象进行比较。
与Comparator的区别
Comparator位于包java.util下,而Comparable位于包java.lang下,Comparable接口将比较代码嵌入自身类中,而后者在一个独立的类中实现比较。
如果类的设计师没有考虑到Compare的问题而没有实现Comparable接口,可以通过 Comparator来实现比较算法进行排序,并且为了使用不同的排序标准做准备,比如:
升序、降序。
*Map接口及其实现类:
Map接口:
Map是从键到值的映射,键不允许重复,每个键最多能映射一个值
Entry接口及实现
Map是键到值的映射,Java集合框架在实现上采用一个个Map.Entry来封装每一个键值对,这样,Map中的元素就变成了Map.Entry的集了,这似乎预示着Map和Set有某种相通性.实际上,在HashSet实现中,HashSet的实现中,HashSet的元素存储在底层就是借助于HashMap来进行的(在部分情况下使用了LinkedHashMap).
Map的实现
在java2集合框架中的Map接口有两个通用实现:
HashMap和TreeMap. HashMap是采用哈希表实现,是Map接口的最好的全面实现.TreeMap实现了Map的子接口SortedMap,采用红黑树作为底层存储结构,提供了按照键排序的Map存储.
2.1HashMap和Hashtable的对比:
HashMap Hashtable
键和值是否允许空 允许 不允许
是否多线程同步 否 是
但是HashMap可以通过如下方式方便地得到HashMap的一个同步视图:
MapsynMap=Collections.synchronizedMap(newHashMap(...));
Hashtable已经经过再造,这是为了保持向后的兼容,保证老版本的程序能够继续正常允许;同时也方便Hashtable和新集合框架进行互操作(新的Hashtable实现了Map接口).正是因为Hashtable经过这些修改,反而使得它混合了新旧的很多特性,过于复杂,臃肿.
新的Map接口采用了比原来Hashtable采用的Enumeration功能更加强大的Iterator遍历工具.
Enumeration现在也不推荐使用,不仅是因为Enumeration没有提供遍历键或值时安全删除Hashtable中的元素的途径;并且Enumeration的名称也不符合Sun的Java命名规范(采用Enumeration更加合适).而Hashtable为了兼容两者,在实现时,不得不提供同时实现了Enumeration和Iterator接口的Enumeration内部类.所以推荐大家用HashMap.
2.2TreeMap
TreeMap中的Tree是一颗平衡二叉树,即每个内部节点都有一个前导节点或者说或者说父节点和两个子节点.存储后继节点的那个成员被命名为left和right.二叉树在平衡时或者叶子节点到根结点的高度在一定的范围内时工作起来是最有效的.平衡一个二叉树的原因是为了缩短从根结点(这是在TreeMap类中惟一能够被直接引用的结点)至每个叶子节点的距离.距离越短,访问那个节点所需时间就会越少.平衡树的定义因实现而异.java2集合框架中的树采用红黑树.红黑树是一种平衡树,这个平衡树的定义是没有一个叶子节点跟其他叶子节点的深度差超过两步.这个名字就是由于树的每个节点都被着上红色和黑色,节点所着的颜色被用来检测树的平衡性.在对节点插入和删除的操作中,可能会被旋转来保持树的平衡性.一般和最坏情况插入,删除,查找时间都是O(lgn).
Map实现的选用
在不需要有序存储时,可以采用高效的HashMap;如果需要有序存储,可以采用TreeMap,但是由于TreeMap是以红黑树进行存储的,需要比HashMap更多的空间和时间的开销.
*遍历Map:
Map集合类用于存储元素对(称作“键”和“值”),其中每个键映射到一个值。
其中键是唯一的(不能有重复对象),而值可以有重复的对象,存的时候,需要指定键和对应的值,取的时候可以根据键名取到值,也可以遍历。
编写代码时,用于存放具有对应关系的键值对
HashMapentrySet()遍历方法
HashMapkeySet()遍历方法
HashMapvalues()遍历方法
三种方法的区别:
values() :
是获取集合中的所有的值----没有键,没有对应关系。
KeySet() :
将Map中所有的键存入到set集合中。
因为set具备迭代器。
所有可以迭代方式取出所有的键,再根据get方法。
获取每一个键对应的值。
迭代后只能通过get()取key。
entrySet():
是返回此映射中包含的映射关系的Set视图。
Map.Entry表示映射关系,迭代后可以e.getKey(),e.getValue()取key和value。
返回的是Entry接口。
For...Each进行遍历
*泛型:
泛型,即“参数化类型”。
一提到参数,最熟悉的就是定义方法时有形参,然后调用此方法时传递实参。
那么参数化类型怎么理解呢?
顾名思义,就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(可以称之为类型形参),然后在使用/调用时传入具体的类型(类型实参)。
练习
1.填空
Collection接口的特点元素是__对象__;
List接口的特点是元素_有_(有|无)顺序,__可以____(可以|不可以)重复;
Set接口的特点是元素___无__(有|无)顺序,__不可以____(可以|不可以)重复;
Map接口的特点是元素是___键值对_______,其中__值___可以重复,___键_____不可以重复。
2.(List)有如下代码
importjava.util.*;
publicclassTestList{
publicstaticvoidmain(Stringargs[]){
Listlist=newArrayList();
list.add(“Hello”);
list.add(“World”);
list.add(1,“Learn”);
list.add(1,“Java”);
printList(list);
}
publicstaticvoidprintList(Listlist){
//1
}
}
要求:
1)把//1处的代码补充完整,要求输出list中所有元素的内容
2)写出程序执行的结果HellojavaLearnWorld
3)如果要把实现类由ArrayList换为LinkedList,应该改哪里?
Listone=newXXXX();
ArrayList和LinkedList使用上有什么区别?
ArrayList数组实现
LinkedList链表实现
实现上有什么区别?
查询快,增删慢
查询慢,增删快
4)如果要把实现类由ArrayList换为Vector,应该改哪里?
Listone=newXXXX();
ArrayList和Vector使用上有什么区别?
要换实现类
实现上有什么区别?
ArrayList轻量级,速度快,线程不安全
Vector重量级,速度慢,线程安全
3.(List)写出下面程序的运行结果
importjava.util.*;
publicclassTestList{
publicstaticvoidmain(Stringargs[]){
Listlist=newArrayList();
list.add(“Hello”);
list.add(“World”);
list.add(“Hello”);
list.add(“Learn”);
list.remove(“Hello”);
list.remove(0);
for(inti=0;i System.out.println(list.get(i)); } } } Hello World 在调用第一个remove方法时,会删掉遇到的第一个“Hello”对象,List中剩下的元素为: WorldHelloLearn 在调用第二个remove方法时,会删掉下标为0的元素。 List中剩下的元素为: HelloWorld 4.(Set,List) importjava.util.*; publicclassTestListSet{ publicstaticvoidmain(Stringargs[]){ Listlist=newArrayList(); list.add(“Hello”); list.add(“Learn”); list.add(“Hello”); list.add(“Welcome”); Setset=newHashSet(); set.addAll(list); System.out.println(set.size()); } } 选择正确答案C A.编译不通过 B.编译通过,运行时异常 C.编译运行都正常,输出3 D.编译运行都正常,输出4 5.(List)已知有一个Worker类如下: publicclassWorker{ privateintage; privateStringname; privatedoublesalary; publicWorker(){} publicWorker(Stringname,intage,doublesalary){ this.name=name; this.age=age; this.salary=salary; } publicintgetAge(){ returnage; } publicvoidsetAge(intage){ this.age=age; } publicStringgetName(){ returnname; } publicvoidsetName(Stringname){ this.name=name; } publicdoublegetSalary(){ returnsalary; } publicvoidsetSalary(doublesalary){ this.salary=salary; } publicvoidwork(){ System.out.println(name+“work”); } } 完成下面的要求 1)创建一个List,在List中增加三个工人,基本信息如下: 姓名年龄工资 zhang3183000 li4253500 wang5223200 2)在li4之前插入一个工人,信息为: 姓名: zhao6,年龄: 24,工资3300 3)删除wang5的信息 4)利用for循环遍历,打印List中所有工人的信息 5)利用迭代遍历,对List中所有的工人调用work方法。 6)为Worker类添加equals方法 6.(Set,Hash算法)为上一题的Worker类,在添加完equals方法的基础上,添加一个 hashCode方法。 publicinthashCode(){ //1 } 有几种写法: 1)return0; 2) intresult=0; if(name! =null)result=name.hashCode(); returnresult+age; 3)returnsuper.hashCode(); 现在要把Worker类放入HashSet中,并希望在HashSet中没有重复元素,则下面说法正 确的是: B A.三种写法都正确 B.1),2)写法正确,2)效率更高 C.2)写法正确,1),3)写法都不正确 7.(Set,Hash算法,方法覆盖)代码改错 importjava.util.*; classWorker{ Stringname; intage; doublesalary; publicWorker(){} publicWorker(Stringname,intage,doublesalary){ this.name=name; this.age=age; this.salary=salary; } inthashCode(){ returnname.hashCode()+age+salary; } publicbooleanequals(Workerw){ if(w.name==name&&w.salary==salary&&w.age==age){ returntrue; }elsereturnfalse; } } publicclassTestWorker{ publicstaticvoidmain(Stringargs[]){ Setset=newHashSet(); set.add(newWorker(“tom”,18,2000)); set.add(newWorker(“tom”,18,2000)); set.add(0,newWorker(“jerry”,18,2000)); System.out.println(set.size()); } } 8.(Set,Hash算法)在前面的Worker类基础上,为Worker类增加相应的方法,使得Worker 放入HashSet中时,Set中没有重复元素。 并编写相应的测试代码。 9.(Set,Comparable接口)在前面的Worker类基础上,为Worker类添加相应的代码, 使得Worker对象能正确放入TreeSet中。 并编写相应的测试代码。 注: 比较时,先比较工人年龄大小,年龄小的排在前面。 如果两个工人年龄相同,则再 比较其收入,收入少的排前面。 如果年龄和收入都相同,则根据字典顺序比较工人姓名。 例 如: 有三个工人,基本信息如下: 姓名年龄工资 zhang3181500 li4181500 wan
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- java 高级 集合 部分 讲课 教案