一、泛型

【引例】
在Dog类和Cat类添加角斗的方法:
狗与狗角斗,猫和锚角斗。
1、创建一个接口
image.png
2、Dog类实现接口
image.png
从上例可以看出,用父类作为接口方法的参数,在子类重写方法时,需要检查子类的真实类型并转型,否则就有可能发生类转换异常。我们可以将方法的接口方法的参数改为泛型,在子类重写方法时,就不需要进行类型检查了。

1.1 什么是泛型

泛型就是在设计时(在编写接口方法时)不需要指定接口方法引用类型参数的类型,在实现时(子类重写方法时)再指定接口方法引用类型参数的类型。即通过给类或接口增加引用类型参数,使得在使用该类时才需要指定引用类型参数的实际对应的类型。从而可以提高程序的灵活性,防止出现运行时类型错误,并可以避免数据的类型转换。比如,一个纸箱可以装苹果,也可以装桔子、玩具等,厂家在生产纸箱时并没有指定这个纸箱需要要装什么东西(可以装苹果、桔子、玩具等),如果是卖苹果商家需要用这个纸箱,就会在纸箱上贴上苹果的标签,我们就不会用这个纸箱去装桔子和玩具了。

1.2 泛型的应用

1、泛型的类定义
类名 <引用类型参数列表>
泛型的接口定义
接口名 <引用类型参数列表>
引用类型参数:用任意大写字母表示,多个参数用逗号分隔。
image.png
2、泛型实现
image.png
如上例,泛型规定了方法fight的对象为Dog类型,调用方法时只能传入Dog类型的对象,不需要检查对象的真实类型和转型了。
泛型的真实类型只能是引用类型,基本数据类型使用包装类型。

二、集合

【引例】学校每学期开设了Java、C++等多门课程供学生选修,每门课程选修的人数不限,统计每个学生的考试成绩。
1、每个学生选了多门课程?不确定。
2、共有多少个学生选修了课程?不确定。
如果用数组来保存选修的情况 ,数组的长度是固定的,而选修课程的学生人数,每个学生选修了多少课程无法确定,显然数组是不适合的。如果有一个数据结构,它的长度随着元素的增加或减少而变化,就可以解决这个问题了。像这样在程序运行时并不知道需要多少对象(元素个数)的情况下,可以使用Java集合。
Java集合为我们提供了一套性能优良、使用方便的接口和类,它们位于java.util包中
image.png
1、Collection:接口存储一组不唯一,无序的对象提供了对集合进行排序、遍历等多种算法实现。
2、Map:存储一组键值对象,提供key到value的映射。

2.1 List接口

List 接口存储一组不唯一,有序(插入顺序)的对象。List接口有2个常用的实现类:
image.png

  • ArrayList实现了长度可变的数组,在内存中分配连续的空间。遍历元素和随机访问元素的效率比较高

image.png

  • LinkedList采用链表存储方式。插入、删除元素时效率比较高

image.png
1、集合的定义
List是一个泛型接口。
List list = new ArrayList<>();
List list = new LinkedList<>();
image.png
2、List接口常用的方法

方法名 说 明
boolean add(Object o) 在列表的末尾顺序添加元素,起始索引位置从0开始
void add(int index,Object o) 在指定的索引位置添加元素。索引位置必须介于0和列表中元素个数之间
int size() 返回列表中的元素个数
Object get(int index) 返回指定索引位置处的元素。取出的元素是Object类型,使用前需要进行强制类型转换
boolean contains(Object o) 判断列表中是否存在指定元素
boolean remove(Object o) 从列表中删除元素
Object remove(int index) 从列表中删除指定位置元素,起始索引位置从0开始

【例2.1-01】
image.png
3、LinkedList的特殊方法

方法名 说 明
void addFirst(Object o) 在列表的首部添加元素
void addLast(Object o) 在列表的末尾添加元素
Object getFirst() 返回列表中的第一个元素
Object getLast() 返回列表中的最后一个元素
Object removeFirst() 删除并返回列表中的第一个元素
Object removeLast() 删除并返回列表中的最后一个元素

【例2.1-02】
image.png
【例2.1-03】完成引例
image.png
1、每个学生选修了多少课程
image.png
image.png
image.png
测试
image.png
2、统计共有多少学生选修课程,打印所有学生成绩
image.png
image.png
image.png
image.png
测试
image.png

2.2 Set接口

Set 接口存储一组唯一,无序的对象 。
无序:指的是元素不按照插入的顺序排序,是散列式排列的,所以没有编号,即不能用get(i)访问元素。
image.png

  • HashSet集合的数据结构是哈希表,所以存储元素的时候使用的原色的hashCode方法来确定位置,如果位置相同,再通过元素的equals()方法判断内容是否相等。
  • TreeSet为使用树型结构进行存储的Set接口提供了一个工具。如果存储的是基本数据类型、存储是会以“自然排序”的方式存储。如果的对象类型,当存储多个会存储出错,因为无法对对象进行排序,但是可以为这个类实现comparable接口,并实现它的compareTo()方法。

1、集合定义
Set set = new HashSet<>();
Set set = new TreeSet<>();
image.png
2、HashSet常用方法

方法 功能描述
public boolean add(E o) 向集合添加指定元素
public void clear() 清空集合中所有元素
public boolean contains(Object o) 判断集合是否包含指定元素
public boolean isEmpty() 判断集合是否还有元素。如果集合不包含任何元素,则返回true
public Iterator iterator() 返回对此集合中元素进行迭代的迭代器
public boolean remove(Object o) 删除集合中的元素
public int size() 返回此集合中的元素的个数
public Object[] toArray 将集合中的元素放到数组中,并返回该数组

【例2.2-01】用Set改写例2.1-01
代码略
3、TreeSet常用方法

方法 功能描述
public E first() 返回有序集合中第一个元素,即最小的那个元素
public E last() 返回有序集合中最后一个元素,即最大的那个元素
public SortedSetsubSet(E fromElement,EtoElement) 返回有序集合从fromElement(包括)到toElement
(不包括)的元素

【例2.2-02】用TreeSet改写例2.2-01,发现了什么?
代码略

三、Map接口

Map接口专门处理键值映射数据的存储(key-value),可以根据键实现对值的操作,Map就像一个字典,我们也经常称之为字典。
image.png

  • HashMap无序,即key是一个HashSet,值是一个List,是最常用的Map实现类。
  • TreeMap默认为升序排序,即key是一个TreeSet。

    3.1 HashMap

    1、Map定义
    Map的key和value都是泛型。
    Map = new HashMap<>();
    image.png
    2、Map的常用方法
方法名 说 明
Object put(Object key, Object val) 以“键-值对”的方式进行存储
Object get (Object key) 根据键返回相关联的值,如果不存在指定的键,返回null
Object remove (Object key) 删除由指定的键映射的“键-值对”
int size() 返回元素个数
Set keySet () 返回键的集合
Collection values () 返回值的集合
boolean containsKey (Object key) 如果存在由指定的键映射的“键-值对”,返回true

【例3.1-01】通过国家英文简称查找国家的中文全名。
image.png
【例3.1-02】根据宠物昵称查找对应宠物,如果找到,显示宠物信息,否则抛出异常 。
image.png
【练习】
1、将1-100之间所有的能被3和5整除的数加入到集合,并将第一个和最后一个元素删除。
2、主人领养了多只宠物,有可能是宠物狗,也有可能是企鹅,输出主人领养的宠物信息。
3、模拟百度翻译,用户输入英语单词,搜索出对应的中文,如果没有找到抛出异常。
4、打印如下表格的数据。

班级 学号 姓名 学分
D01 D0101 黄小明 20
D0102 张兰 22
D02 D0201 李英 20
D0202 王峥嵘 24
D0203 刘小东 22