Day15
一、泛型
1、泛型是对类、接口、方法的约束,也是作为一个参数来替换所有的类型(泛型《T、E、W、K、V等》中没有继承)
2、场景:当不知道集合存储什么类型的数据的时候就使用泛型
3、实例化集合泛型的语法:jdk1.7之后,ArrayList list=new ArrayList<……这个括号也可以省略……>()
4、没有泛型的时候,默认的是Oject类型,所有的数据类型都可以存储;但不安全,会报错,而且想取某类型数据时不方便(java.lang.ClassCastException强制类型转换错误)
泛型的好处:
(1)避免强制转型;(2)把运行错误提前到编译错误;
泛型的坏处:
只能都存储一种数据类型
- 注意点:如果使用迭代器来遍历集合,迭代器的泛型必须与集合的泛型是一样的
5、泛型约束类(public class ArrayList)
- 语法:访问修饰符 关键字(class) 类名<泛型>{ 类的具体的内容 }
注意点:
- 在写这个类的具体信息的时候,没有给其具体的类型,但在new一个对象的时候必须给其具体的类型
- 在给类加泛型之后,类里所有的变量、非静态方法都可以使用这个泛型
6、泛型约束方法
- 语法:访问修饰符<泛型> 返回值类型 方法名(参数《可以使用泛型的数据类型》){ 方法体 }
调用这个方法的时候必须知道它的数据类型,不能再使用泛型
静态方法可以加泛型,但是静态方法不能使用类的泛型,只能使用方法自己定义的泛型
7、泛型约束接口
- 语法:访问修饰符 interface 接口名称{ 抽象方法 }
如果接口有泛型,实现类有两种表现形式:
1.实现类不能确定其泛型的具体类型,则只需在new对象时确定泛型的具体类型即可
2.实现类确定泛型的具体类型《参照public final class Scanner implements Iterator》
8、泛型通配符(?)
- 表示的是任意的泛型
- 特点:
1.不能在实例化的时候给任意泛型(?)
2.一般是作为参数的类型
注意:
- <? extends E>:表示E泛型的子类或者它本身
- <? super E>:表示E泛型的父类或者它本身
二、Set接口
1、特点:
- 父类是Collection
- 不能包含重复的元素
- 没有顺序,没有索引,不能使用普通的for循环遍历
2、子类HashSet
(1)底层是由哈希表结构进行存储的,哈希表结构是数组+链表式或数组+红黑树《jdk1.8后》(查询速度较快)
(2)不能包含重复的元素,可以包含("")空串
底层检查是否重复,执行了两个方法:HashCode()《判断哈希值,即地址是否一样》、equals()《判断值是否一样》
3、HashSet常规方法:(跟ArrayList相比,没有get、set方法)
public boolean add(E e):添加元素;
public boolean contains(Object o):判断集合是否包含指定的元素;
public boolean isEmpty():判断是否为空;
public boolean remove(Object o):删除元素;
public int size():返回集合的长度;
4、对HashSet集合进行遍历
- 不使用泛型,转换成数组的方式,遍历数组
- 使用泛型,转换成数组
- 使用泛型,然后用迭代器进行遍历
- 使用泛型,直接用增强for循环遍历集合
Set集合不能存储重复值,因为实际上Set底层使用了Map集合来进行存储,Map是以键值对的方式进行存储的,而Map的键是不能够重复的
5、LinkedList是有序的Set集合,它是HashSet的子类,采用的存储方法是:数组+双重链表式
- 第一种链表是用来把相同hash值的元素进行串联
- 第二种链表是用来纪录每一个值的顺序