程序基础及设计 8_第1页
程序基础及设计 8_第2页
程序基础及设计 8_第3页
程序基础及设计 8_第4页
程序基础及设计 8_第5页
已阅读5页,还剩64页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

单元6集合框架Java程序设计基础教程(AI助学)(慕课版)人民邮电出版社有一位热爱户外运动的摄影爱好者,他在追寻自然美景的过程中积累了大量的照片和拍摄地点信息。为了高效地管理这些信息,他决定利用Java集合框架。其中,List接口如同一个有序的照片库,能够帮助摄影爱好者按拍摄时间整理照片;Set接口可确保每个拍摄地点都是独一无二的,避免了重复记录的困扰。这些接口都继承Collection接口,后者为集合操作提供了统一的标准。此外,泛型的应用使得集合能够存储特定类型的对象,如照片或地点信息,增强了代码的类型安全性和可读性。而Lambda表达式的引入,为集合的遍历、筛选和转换等操作带来了前所未有的便捷,让摄影爱好者能够以前所未有的高效方式查找、定位和整理他的摄影作品及拍摄地点信息。通过学习本单元内容,读者将深入了解Collection、List、Set、Map接口的特性和常用实现类,以及泛型和Lambda表达式的应用,了解它们的适用场景,并学会如何选择正确的集合类型来满足不同的需求。这些知识将对摄影和户外探险提供强大的支持,让读者能够更轻松地整理及管理照片和地点信息,记录下美好的瞬间。本章导读Thechapter’sintroduction目录导航6.1集合概述6.2

Collection接口6.3

List接口6.4

Set接口6.5

Map接口6.6泛型6.7

Lambda表达式6.8【商业实例】“银行提款机”

项目——历史转账记录6.9

【综合实训】使用TreeSet

类自定义排序6.1集合概述在Java中,集合是一种用于存储和操作多个对象的容器。集合具有支持动态大小、数据操作便捷、数据结构丰富的特点,可以灵活地对数据进行各种操作。常用的集合接口有Collection、List、Set和Map等,各接口下的实现类有很多,每个类都有自己的特点。Collection接口是Java集合框架中的顶层接口,用于定义单列集合(即只能存储单个类型元素的集合)的基本操作。它定义了添加、移除、遍历等通用方法,但不提供具体的实现。其子接口List和Set分别代表有序集合和无序集合,List允许元素重复,而Set不允许。Collection接口的实现类有ArrayList、LinkedList、HashSet等,分别基于不同的数据结构实现了这些基本操作,为开发者提供了丰富的集合操作选择。Map接口是一种将键映射到值的对象,一个键最多映射到一个值。Map接口的实现类主要包括HashTable、HashMap、TreeMap。目录导航6.1集合概述6.2

Collection接口6.3

List接口6.4

Set接口6.5

Map接口6.6泛型6.7

Lambda表达式6.8【商业实例】“银行提款机”

项目——历史转账记录6.9

【综合实训】使用TreeSet

类自定义排序6.2Collection接口Collection接口定义了单列集合的基本操作方法,其常用方法如表所示。类别方法功能描述添加元素add(Eelement)将指定元素添加到当前集合中addAll(Collection<?extendsE>c)将指定集合中的所有元素添加到当前集合中移除元素clear()移除当前集合中的所有元素remove(Objecto)从当前集合中移除指定元素的一个实例(如果存在)removeAll(Collection<?>c)移除当前集合包含在指定集合中的所有元素retainAll(Collection<?>c)移除当前集合未包含在指定集合中的元素查询元素contains(Objecto)如果当前集合包含指定的元素,则返回truecontainsAll(Collection<?>c)如果当前集合包含指定集合中的所有元素,则返回trueisEmpty()如果当前集合不包含元素,则返回truesize()返回当前集合中的元素数迭代元素iterator()返回在当前集合的元素上进行迭代的迭代器将集合转换为数组toArray()返回包含当前集合中所有元素的数组toArray(T[]a)返回包含当前集合中所有元素的数组,返回的数组的运行时类型是指定数组的运行时类型比较和哈希equals(Objecto)比较当前集合与指定对象是否相等hashCode()返回当前集合的哈希值目录导航6.1集合概述6.2

Collection接口6.3

List接口6.4

Set接口6.5

Map接口6.6泛型6.7

Lambda表达式6.8【商业实例】“银行提款机”

项目——历史转账记录6.9

【综合实训】使用TreeSet

类自定义排序6.3List接口List接口是Java集合框架中的一个基本接口,它继承Collection接口,表示一个有序的集合,并且继承了Collection接口的所有功能方法,增加了一些自己的方法,允许包含重复元素,元素是按照添加顺序保存的。List接口的常用方法如表6.2所示。类别方法功能描述添加元素add(Eelement)将指定的元素添加到列表的末尾add(intindex,Eelement)在指定的位置添加指定的元素访问元素get(intindex)返回列表中指定位置的元素indexOf(Objecto)返回指定元素在列表中第一次出现的索引,如果列表不包含该元素,则返回-1移除元素remove(intindex)移除列表中指定位置的元素remove(Objecto)从列表中移除第一个出现的指定元素,如果列表不包含该元素,则不做任何操作clear()从列表中移除所有元素获取元素个数size()返回列表中的元素个数表6.2List接口的常用方法6.3.1ArrayList类1.动态大小ArrayList的大小可以根据需要动态变化,不需要手动设置。2.随机访问ArrayList支持按索引(位置)快速访问元素,时间复杂度为O(1)。3.元素允许重复ArrayList中可以包含重复的元素。//创建ArrayListArrayList<String>list=newArrayList<>();//添加元素list.add("Java");list.add("Python");list.add("C++");//访问元素Stringlanguage=list.get(0);//获取第一个元素//修改元素list.set(1,"JavaScript");//将第二个元素修改为“JavaScript”//移除元素list.remove("C++");//移除指定元素list.remove(1);//移除索引为1的元素//遍历元素for(Stringlang:list){System.out.println(lang);}//获取元素个数intsize=list.size();//返回1,因为移除了两个元素6.3List接口ArrayList类在创建时默认大小为10,通过add()方法依次添加元素,若超出当前容量则自动扩容。ArrayList类内部采用动态数组存储元素,支持高效随机访问和尾部添加。(1)创建ArrayList,默认大小为10List<Integer>list=newArrayList<>();(2)向ArrayList中添加元素3list.add(3);6.3List接口(3)向ArrayList中添加元素4list.add(4);(4)向ArrayList中添加元素5list.add(5);6.3.2LinkedList类LinkedList是Java集合框架中的一个类,实现了List接口。LinkedList类基于双向链表实现,与ArrayList不同的是,LinkedList不是基于动态数组,而是由一系列节点(Node)组成的。01基于双向链表LinkedList使用双向链表实现,每个节点都存储数据元素以及指向前后节点的引用02添加和移除高效由于使用了链表结构,LinkedList的添加和移除操作非常高效,不需要移动大量元素03随机访问相对较慢与ArrayList不同,LinkedList不支持快速随机访问,因为访问特定位置的元素需要从头部或尾部开始遍历链表6.3.2LinkedList类1.添加元素add(Eelement):将指定的元素添加到列表的末尾。add(intindex,Eelement):在指定的位置添加指定的元素。2.访问元素get(intindex):返回列表中指定位置的元素。getFirst():返回列表中的第一个元素。getLast():返回列表中的最后一个元素。6.3.2LinkedList类3.移除元素remove(intindex):移除列表中指定位置的元素。remove(Objecto):从列表中移除第一个出现的指定元素,如果列表中不包含该元素,则不做任何操作。removeFirst():移除并返回列表中的第一个元素。removeLast():移除并返回列表中的最后一个元素。clear():从列表中移除所有的元素。6.3.2LinkedList类4.其他常用方法size():返回列表中元素的个数。下面使用LinkedList类来添加、访问、修改、移除和遍历元素,并获取元素个数。//创建LinkedListLinkedList<String>linkedList=newLinkedList<>();//添加元素linkedList.add("Java");linkedList.add("Python");linkedList.add("C++");//访问元素StringfirstLanguage=linkedList.getFirst();//获取第一个元素StringlastLanguage=linkedList.getLast();//获取最后一个元素//修改元素(LinkedList不提供setter方法,需要先移除元素再添加元素)linkedList.remove("Java");linkedList.addFirst("JavaScript");//在第一个位置添加新元素//移除元素linkedList.removeLast();//移除最后一个元素//遍历元素for(Stringlang:linkedList){System.out.println(lang);}//获取元素个数intsize=linkedList.size();//返回2,因为移除了一个元素6.3.2LinkedList类LinkedList类的运行方式如下。List<Integer>list=newLinkedList<>();list.add(3);创建LinkedList,这个时候会初始化两个指针(引用)。向LinkedList中添加元素36.3.2LinkedList类list.add(4);list.add(5);向LinkedList中添加元素4向LinkedList中添加元素5目录导航6.1集合概述6.2

Collection接口6.3

List接口6.4

Set接口6.5

Map接口6.6泛型6.7

Lambda表达式6.8【商业实例】“银行提款机”

项目——历史转账记录6.9

【综合实训】使用TreeSet

类自定义排序6.4Set接口Set接口是Java集合框架中的一种集合类型,它继承Collection接口。Set接口表示一个不包含重复元素的集合。在集合中,元素的顺序通常是未指定的(与元素的添加顺序无关),并且元素不能重复。Set接口的实现类通常用于存储无序、不重复的元素。不允许元素重复Set中的元素是唯一的,不允许重复不保证元素顺序Set接口不保证元素的顺序,具体实现类的顺序可能不同常用于去重不允许元素重复,因此Set接口常用于去除集合中的重复元素6.4Set接口1.添加元素add(Eelement):将指定的元素添加到集合中。2.移除元素remove(Objecto):从集合中移除指定的元素。clear():从集合中移除所有元素。3.判断元素是否存在contains(Objecto):判断集合中是否包含指定的元素。isEmpty():判断集合是否为空,即是否不包含任何元素。6.4Set接口4.集合操作addAll(Collection<?extendsE>c):将另一个集合中的所有元素添加到当前集合中。retainAll(Collection<?>c):保留当前集合中指定集合也包含的元素,移除其他元素。removeAll(Collection<?>c):移除当前集合中指定集合也包含的元素。5.其他常用方法size():返回集合中元素的个数。iterator():返回一个迭代器,用于遍历集合中的元素。6.4Set接口下面使用Set接口来添加元素、判断元素是否存在、移除元素和遍历元素,并获取元素个数。//创建SetSet<String>set=newHashSet<>();//添加元素set.add("Apple");set.add("Banana");set.add("Orange");//判断元素是否存在booleancontainsApple=set.contains("Apple");//返回true//移除元素set.remove("Banana");//遍历元素for(Stringfruit:set){System.out.println(fruit);}//获取元素个数intsize=set.size();//返回2,因为移除了一个元素6.4.1HashSet类HashSet是Java集合框架中实现了Set接口的类,基于哈希表实现。当添加一个元素时,HashSet类会使用该元素的哈希值来计算其在哈希表中的存储位置,并将该元素存储在该位置上。HashSet类的底层数据结构是数组和链表的组合。(1)哈希值哈希值(HashValue)又称散列值,是通过哈希函数(HashFunction)对输入数据(如字符、文件等)进行计算得出的一串固定长度的数值。假设有一个巨大的图书馆,这个图书馆中有成千上万本图书,需要一种能快速找到想要的图书的方法。如果每本图书都有一个独一无二的编号,就可以通过编号快速找到想要的图书。这个编号就是哈希值。这个编号是通过一个特殊的函数(哈希函数)生成的。这个函数会把图书的名称、作者、出版日期等信息作为输入,并计算出一个独特的编号。这个计算过程就像是给图书做指纹识别,每本图书都会有一个独一无二的指纹,即哈希值。6.4.1HashSet类(2)HashSet类底层数组数组是HashSet类的主体,数组中的每一个元素都可以看作bucket(桶),可以存放一个或者多个HashSet元素。(3)HashSet类底层链表当通过哈希函数计算出的哈希值相同(即出现哈希冲突)时,这些键值对或元素会以链表的形式存储在同一个bucket中。链表中的每一个节点就是一个HashSet元素。HashSet类的特点如下。01不允许元素重复HashSet类中的元素是唯一的,不允许重复02不保证元素顺序HashSet类不保证元素的顺序,即添加的顺序不一定是遍历的顺序基于哈希表HashSet类使用哈希表数据结构实现,可以快速地进行添加、移除和查找操作6.4.1HashSet类HashSet类的常用方法如下。1.添加元素add(Eelement):将指定的元素添加到集合中。2.移除元素remove(Objecto):从集合中移除指定的元素。clear():从集合中移除所有元素。3.判断元素是否存在contains(Objecto):判断集合中是否包含指定的元素。isEmpty():判断集合是否为空,即是否不包含任何元素。6.4.1HashSet类4.其他常用方法size():返回集合中元素的个数。iterator():返回一个迭代器,用于遍历集合中的元素。下面使用HashSet类来添加元素、判断元素是否存在、移除元素和遍历元素,并获取元素个数。//创建HashSetHashSet<String>hashSet=newHashSet<>();//添加元素hashSet.add("Apple");hashSet.add("Banana");hashSet.add("Orange");//判断元素是否存在booleancontainsApple=hashSet.contains("Apple");//返回true//移除元素hashSet.remove("Banana");//遍历元素for(Stringfruit:hashSet){System.out.println(fruit);}//获取元素个数intsize=hashSet.size();//返回2,因为移除了一个元素6.4.1HashSet类Set<String>set=newHashSet<>();set.add("Alice");创建HashSet集合,HashSet的默认数组大小为16。向集合中添加字符串"Alice",假设哈希值为“A”。HashSet类运行时的内存状态如下。6.4.1HashSet类set.add("Bob");set.add("Charlie");向集合中添加字符串"Bob",假设哈希值为“B”。向集合中添加字符串"Charlie",假设哈希值为“C”。6.4.1HashSet类set.add("Bobby");向集合中添加字符串"Bobby",假设哈希值为“B”,会以链表的形式追加元素6.4.2TreeSet类TreeSet类基于红黑树实现。它确保集合元素处于有序状态,不允许元素重复,提供快速查找、添加和移除元素的功能。红黑树的特点如下。每个节点要么是红色的,要么是黑色的根节点是黑色的每个叶子节点都是黑色的如果一个节点是红色的,那么它的子节点必须是黑色的(即不能有两个连续的红色节点)从任意节点到其每个叶子节点的所有路径都包含相同数目的黑色节点6.4.2TreeSet类TreeSet类具有以下特点。有序性TreeSet类中的元素是有序的,根据元素的自然顺序或者指定的比较器顺序进行排列不允许元素重复TreeSet类中的元素是唯一的,不允许重复基于红黑树TreeSet类使用红黑树数据结构实现,支持高效的添加、移除和查找操作6.4.2TreeSet类TreeSet类的常用方法如下。1.添加元素add(Eelement):将指定的元素添加到集合中。2.移除元素remove(Objecto):从集合中移除指定的元素。clear():从集合中移除所有的元素。3.判断元素是否存在contains(Objecto):判断集合中是否包含指定的元素。isEmpty():判断集合是否为空,即是否不包含任何元素。6.4.2TreeSet类4.集合操作addAll(Collection<?extendsE>c):将另一个集合中的所有元素添加到当前集合中。retainAll(Collection<?>c):保留当前集合中指定集合也包含的元素,移除其他元素。removeAll(Collection<?>c):移除当前集合中指定集合也包含的元素。5.获取元素first():返回集合中的第一个(最小的)元素。last():返回集合中的最后一个(最大的)元素。6.4.2TreeSet类下面使用TreeSet类来添加元素、判断元素是否存在、移除元素和遍历元素(有序),并获取元素个数。//创建TreeSetTreeSet<String>treeSet=newTreeSet<>();//添加元素treeSet.add("Apple");treeSet.add("Banana");treeSet.add("Orange");//判断元素是否存在booleancontainsApple=treeSet.contains("Apple");//返回true//移除元素treeSet.remove("Banana");//遍历元素(有序)for(Stringfruit:treeSet){System.out.println(fruit);//输出:Apple,Orange}//获取元素个数intsize=treeSet.size();//返回2,因为移除了一个元素TreeSet类通常用于需要按照元素的自然顺序或者指定的比较器顺序进行排列的场景。在需要排序的集合中,它支持高效的添加、移除和查找操作。需要注意的是,由于它是有序的,添加、移除和查找操作的时间复杂度通常为O(logn),其中n是集合的大小。6.4.2TreeSet类操作时TreeSet类的内部运行状态如下。Set<String>set=newTreeSet<>();set.add("A");(2)向TreeSet中添加字符"A"。(1)创建TreeSet集合。set.add("B");(3)向TreeSet中添加字符"B"。set.add("C");set.add("D");(5)向TreeSet中添加字符"D"。(4)向TreeSet中添加字符"C"。6.4.2TreeSet类HashSet类与TreeSet类的区别如表6.3所示。HashSet类TreeSet类底层结构哈希表红黑树添加/移除/查找耗时O(1)O(logn)是否有序不一定有序关于key有序线程安全不安全不安全添加/移除/查找的区别先计算key哈希地址,然后增删按照红黑树的特性增删比较与覆写需要覆写equals()与hashCode()方法key具有比较能力应用场景对时间效率有要求时需要key有序时表6.3HashSet类与TreeSet类的区别目录导航6.1集合概述6.2

Collection接口6.3

List接口6.4

Set接口6.5

Map接口6.6泛型6.7

Lambda表达式6.8【商业实例】“银行提款机”

项目——历史转账记录6.9

【综合实训】使用TreeSet

类自定义排序6.5Map接口Map接口表示的是一种键值对(key-value)的映射关系。在一个Map集合中,每个键(key)都映射到一个对应的值(value)。Map接口的主要实现类有HashMap、TreeMap、LinkedHashMap等。键的唯一性Map集合中的每个键都是唯一的,不允许重复。如果使用已经存在的键来添加新的值,则新的值会覆盖旧的值。Map接口建立了键和值之间的关联,通过键,可以快速找到对应的值。键和值的关联01OPTION02OPTION6.5Map接口无序性Map集合中的键值对是无序的,即添加的顺序不一定是遍历的顺序。Map接口的常用方法如下。03OPTIONput(Kkey,Vvalue):将指定的键值对添加到集合中。get(Objectkey):返回指定键对应的值。containsKey(Objectkey):判断集合中是否包含指定的键。containsValue(Objectvalue):判断集合中是否包含指定的值。remove(Objectkey):移除指定键对应的键值对。size():返回集合中键值对的数量。isEmpty():判断集合是否为空,即是否不包含任何键值对。6.5Map接口下面使用Map接口来创建映射、添加键值对、获取值、判断键是否存在以及遍历键值对。//创建HashMapMap<String,Integer>map=newHashMap<>();//添加键值对map.put("Alice",25);map.put("Bob",30);map.put("Charlie",28);//获取值intage=map.get("Bob");//返回30//判断键是否存在booleancontainsAlice=map.containsKey("Alice");//返回true//遍历键值对for(Map.Entry<String,Integer>entry:map.entrySet()){System.out.println(entry.getKey()+":"+entry.getValue());}/*输出内容如下。Alice:25Bob:30Charlie:28*/在这个示例中,使用了HashMap类来实现Map接口。可以根据需要选择不同的Map实现类,每种实现类都有它自己的特点和适用场景。6.5.1HashMap类HashMap类的主要特点如下。键值对存储HashMap类使用键值对的方式存储数据。其中,每个键都是唯一的,每个键映射到一个特定的值基于哈希表HashMap类的底层数据结构是哈希表,这使得添加、移除和查找操作的平均时间复杂度为O(1),即常数时间不保证有序性HashMap类不保证元素的顺序,即添加的顺序不一定是遍历的顺序允许空键值HashMap类允许键和值为null,既可以将null作为键,又可以将null作为值非线程安全HashMap类不是线程安全的,如果在多线程环境下使用,则需要进行额外的同步处理01020304056.5.1HashMap类HashMap类是一个重要的数据结构,它实现了Map接口。在HashMap类的内部,所有的键值对(即条目)都存储在一个名为bucket的数组中。当多个键的哈希值映射到同一个bucket时,就会发生所谓的“哈希冲突”。为了处理这种冲突,HashMap类会在该bucket中创建一个链表,所有哈希值冲突的键值对都会存储在这个链表中。当链表的长度超过一定的阈值(默认为8)时,HashMap类会将链表转换为红黑树。HashMap类通过动态地在链表和红黑树之间转换来平衡内存占用和性能。红黑树的转换如图6.2所示。图6.2红黑树的转换6.5.1HashMap类HashMap类的常用方法如下。1.添加和获取元素put(Kkey,Vvalue):将键值对添加到HashMap中。get(Objectkey):返回指定键对应的值。2.移除元素remove(Objectkey):移除指定键对应的键值对。3.判断键是否存在containsKey(Objectkey):判断HashMap中是否包含指定的键。6.5.1HashMap类4.获取键值对数量size():返回HashMap中键值对的数量。5.遍历键值对使用迭代器或者增强型for循环来遍历HashMap类中的键值对。//创建HashMapHashMap<String,Integer>hashMap=newHashMap<>();//添加键值对hashMap.put("Alice",25);hashMap.put("Bob",30);hashMap.put("Charlie",28);//获取值intage=hashMap.get("Bob");//返回30//判断键是否存在booleancontainsAlice=hashMap.containsKey("Alice");//返回true//遍历键值对下面使用HashMap类来存储和操作键值对数据。for(Map.Entry<String,Integer>entry:hashMap.entrySet()){System.out.println(entry.getKey()+":"+entry.getValue());}/*输出内容如下。Alice:25Bob:30Charlie:28*/6.5.2TreeMap类TreeMap类是Java集合框架中实现了SortedMap接口的类,它继承AbstractMap类,底层使用红黑树实现。TreeMap类的主要特点如下。TreeMap类中的键值对是有序的,可以选择按照键的自然顺序(如果键实现了Comparable接口)或者提供的比较器顺序进行排列有序性01TreeMap类使用红黑树作为底层数据结构,这种自平衡的二叉查找树确保了高效的添加、移除和查找操作基于红黑树02与其他Map实现类一样,TreeMap类中的键是唯一的,不同的键映射到不同的值键是唯一的03TreeMap类提供了一系列方法,如firstKey()、lastKey()、headMap(KtoKey)和tailMap(KfromKey)等,可以返回有序的子集或者具有特定顺序的元素提供了有序的视图04TreeMap类允许键为null,但是只能有一个键为null允许空键(但是有限制)056.5.2TreeMap类TreeMap类的常用方法如下。1.添加和获取元素put(Kkey,Vvalue):将键值对添加到TreeMap中。get(Objectkey):返回指定键对应的值。2.移除元素remove(Objectkey):移除指定键对应的键值对。3.判断键是否存在containsKey(Objectkey):判断TreeMap中是否包含指定的键。6.5.2TreeMap类4.获取键值对数量size():返回TreeMap中键值对的数量。5.有序遍历keySet():返回包含TreeMap键的Set,按照键的顺序排列。values():返回包含TreeMap值的Collection,按照键的顺序排列。//创建TreeMapTreeMap<String,Integer>treeMap=newTreeMap<>();//添加键值对treeMap.put("Alice",25);treeMap.put("Bob",30);treeMap.put("Charlie",28);//获取值intage=treeMap.get("Bob");//返回30//判断键是否存在booleancontainsAlice=treeMap.containsKey("Alice");//返回true//遍历键值对(按照键的顺序下面使用TreeMap类来存储和操作键值对数据。for(Map.Entry<String,Integer>entry:treeMap.entrySet()){System.out.println(entry.getKey()+":"+entry.getValue());}/*输出内容如下。Alice:25Bob:30Charlie:28*///获取第一个和最后一个键StringfirstKey=treeMap.firstKey();//返回AliceStringlastKey=treeMap.lastKey();//返回Charlie目录导航6.1集合概述6.2

Collection接口6.3

List接口6.4

Set接口6.5

Map接口6.6泛型6.7

Lambda表达式6.8【商业实例】“银行提款机”

项目——历史转账记录6.9

【综合实训】使用TreeSet

类自定义排序6.6.1泛型的概念泛型允许在类、接口、方法中使用类型参数。泛型的出现使代码更加灵活、可读性更高,提供了类型安全的编程环境。1.泛型的优点通过泛型,可以编写更加通用的代码,适用于多种数据类型提高代码可重用性泛型使得代码更加清晰易懂,尤其是在处理复杂的数据结构时提高代码可读性使用泛型后,大多数情况下不需要进行强制类型转换,代码更加简洁消除强制类型转换泛型提供了编译时的类型检查,能够在编译期间发现类型错误,避免了运行时类型转换异常类型安全泛型的优点6.6.1泛型的概念2.泛型的使用场景泛型接口与泛型类类似,在定义接口时声明一个或多个类型参数02泛型类在定义类时声明一个或多个类型参数,这些类型参数在类的成员变量、方法参数、方法返回值等位置可以使用01泛型方法在定义方法时声明一个或多个类型参数,这些类型参数只在该方法的作用域内有效036.6.1泛型的概念3.泛型类的使用publicclassGenericClass<T>{privateTdata;publicvoidsetData(Tdata){this.data=data;}publicTgetData(){returndata;}}泛型类允许在类中使用类型参数,以便在创建对象时指定具体的数据类型。泛型类的定义形式如下。GenericClass<Integer>integerObj=newGenericClass<>();integerObj.setData(42);intvalue=integerObj.getData();//不需要进行类型转换GenericClass<String>stringObj=newGenericClass<>();stringObj.setData("Hello,Generics!");Stringmessage=stringObj.getData();//不需要进行类型转换使用泛型类时,可以指定具体的类型。示例代码如下。6.6.2泛型的方法和接口public<T>TfindMax(T[]array){Tmax=array[0];for(Titem:array){if(pareTo(max)>0){max=item;}}returnmax;}除了类可以使用泛型,方法还可以定义为泛型方法。示例代码如下。publicinterfaceGenericInterface<T>{voidsetData(Tdata);TgetData();}publicclassStringHolderimplementsGenericInterface<String>{privateStringdata;publicvoidsetData(Stringdata){this.data=data;}publicStringgetData(){returndata;}}接口也可以使用泛型,泛型接口的定义形式和泛型类类似。示例代码如下。6.6.3泛型通配符的使用Java的泛型通配符用于表示未知类型。“?”表示任意类型“?extendsT”表示T或T的子类型“?superT”表示T或T的父类型6.6.3泛型通配符的使用无界通配符(UnboundedWildcard)即“?”。它表示任意类型,在需要使用泛型但又不关心实际类型时非常有用。publicvoidprintList(List<?>list){for(Objectitem:list){System.out.println(item);}}上界通配符(UpperBoundedWildcard)即“?extendsT”。它表示类型参数是T或者T的子类型。publicvoidprocessNumbers(List<?extendsNumber>list){for(Numbernumber:list){System.out.println(number);}}下界通配符(LowerBoundedWildcard)即“?superT”。它表示类型参数是T或者T的父类型。publicvoidaddNumbers(List<?superInteger>list){for(inti=1;i<=10;i++){list.add(i);}}目录导航6.1集合概述6.2

Collection接口6.3

List接口6.4

Set接口6.5

Map接口6.6泛型6.7

Lambda表达式6.8【商业实例】“银行提款机”

项目——历史转账记录6.9

【综合实训】使用TreeSet

类自定义排序6.7.1Lambda表达式语法Lambda表达式的基本语法如下。(parameters)->expression(parameters)->{statements;}另一种语法如下。parameters是参数列表,可以为空或包含一个或多个参数;expression是表达式,或者是用花括号括起来的代码块。如果Lambda表达式有参数,参数的类型可以被编译器推断出来,则无须显式声明。如果Lambda表达式的代码块中有多条语句,则需要使用花括号括起来,并且需要使用return语句来返回值。6.7.1Lambda表达式语法()->System.out.println("Hello,Lambda!");(name)->System.out.println("Hello,"+name);无参数的Lambda表达式带一个参数的Lambda表达式以下是一些Lambda表达式的例子。(inta,intb)->a+b(inta,intb)->{intsum=a+b;System.out.println("Sum:"+sum);returnsum;}带多个参数的Lambda表达式Lambda表达式包含多条语句6.7.2函数式接口函数式接口的设计是为了支持Lambda表达式,它允许Lambda表达式被赋值给该接口的实例。函数式接口可以包含一个抽象方法,也可以包含从java.lang.Object继承的方法,如toString()、equals(Objectobj)等。Lambda表达式通常与Java的函数式接口一起使用,函数式接口是只有一个抽象方法的接口。Runnablerunnable=()->System.out.println("Hello,Lambda!");可以使用@FunctionalInterface注解使用@FunctionalInterface注解可以确保一个接口是函数式接口可以有默认方法和静态方法函数式接口可以包含多个默认方法和静态方法只有一个抽象方法函数式接口只能有一个抽象方法,这个方法为函数式接口的目标方法(FunctionalMethod)6.7.3构造方法与方法的引用Lambda表达式不仅可以作为函数式接口的实例,还可以与构造方法和方法的引用一起使用,使得代码更加简洁。1.Lambda构造方法的引用Lambda构造方法的引用允许直接引用类的构造方法,它的语法是ClassName::new。这种引用适用于构造方法没有参数的情况。示例代码如下。//无参构造方法引用Supplier<MyClass>supplier=MyClass::new;MyClassinstance=supplier.get();//创建MyClass的实例//带参构造方法引用Function<String,MyClass>constructor=MyClass::new;MyClassinstance=constructor.apply("parameter");//创建带参数的MyClass实例如果构造方法带参数,则可以使用带参数的函数式接口(如Function、BiFunction等),通过Lambda表达式引用构造方法。示例代码如下。6.7.3构造方法与方法的引用2.Lambda方法的引用Lambda方法的引用允许直接引用现有类或对象的方法,它的语法是ClassName::methodName或instance::methodName。示例代码如下。//静态方法引用Function<String,Integer>parseInt=Integer::parseInt;intnumber=parseInt.apply("123");/*调用Integer.parseInt()方法将字符串转换为整数*///实例方法引用List<String>list=Arrays.asList("apple","orange","banana");list.forEach(System.out::println);/*调用System.out.println()方法输出列表中的每个元素*/在这个示例中,System.out::println是PrintStream类的println()方法的引用,可以作为forEach()方法的参数。目录导航6.1集合概述6.2

Collection接口6.3

List接口6.4

Set接口6.5

Map接口6.6泛型6.7

Lambda表达式6.8【商业实例】“银行提款机”

项目——历史转账记录6.9

【综合实训】使用TreeSet

类自定义排序【商业实例】“银行提款机”项目——历史转账记录在“银行提款机”项目中,首先,定义一个Record类,用于存储转账信息,包括转账人姓名、收款人姓名、转账时间和转账金额。其次,在main()函数或测试类中创建多个Record对象并将它们添加到一个列表中,模拟多条转账记录。最后,使用Lambda表达式,通过条件过滤实现对特定人员转账记录的检索。这种方式使得代码更加简洁、易读,并提高了代码的灵活性。【商业实例】“银行提款机”项目——历史转账记录任务1:定义Record类publicclassRecord{/***转账人姓名*/privateStringtransferor;/***收款人姓名*/privateStringcollector;/***转账时间*/privateLocalDateTimetransferTime;/***转账金额*/privateDoubletransferAmount;publicRecord(){}定义一个Record类,在该类中定义属性——转账人姓名(transferor)、收款人姓名(collector)、转账时间(transferTime)、转账金额(transferAmount)。【商业实例】“银行提款机”项目——历史转账记录publicRecord(Stringtransferor,Stringcollector,LocalDateTimetransferTime,DoubletransferAmount){this.transferor=transferor;this.collector=collector;this.transferTime=transferTime;this.transferAmount=transferAmount;}publicStringgetTransferor(){returntransferor;}publicvoidsetTransferor(Stringtransferor){this.transferor=transferor;}publicStringgetCollector(){returncollector;}publicvoidsetCollector(Stringcollector){this.collector=collector;}publicLocalDateTimegetTransferTime(){returntransferTime;}publicvoidsetTransferTime(LocalDateTimetransferTime){this.transferTime=transferTime;}publicDoublegetTransferAmount(){returntransferAmount;}publicvoidsetTransferAmount(DoubletransferAmount){this.transferAmount=transferAmount;}}【商业实例】“银行提款机”项目——历史转账记录任务2:在main()函数中添加转账记录在main()函数中定义几条转账记录,分别使用不同的参数,构建出一个记录集。publicstaticvoidmain(String[]args){

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论