Java15-day06【Set、HashSet、LinkedHashSet、TreeSet、Comparable、Comparator、泛型类、可变参数的使用】

目   录

01_Set集合概述和特点

3.1、Set集合概述和特点

02_哈希值

3.2、哈希值

03_HashSet集合概述和特点

3.3、HashSet集合概述和特点

04_HashSet集合保证元素唯一性源码分析

3.4、HashSet集合保证元素唯一性源码分析

05_常见数据结构之哈希表

3.5、常见数据结构之哈希表

06_HashSet集合存储学生对象并遍历

案例:HashSet集合存储学生对象并遍历

自动生成hashCode()与equals()方法:快捷键 Alt + Insert

07_LinkedHashSet集合概述和特点

3.6、LinkedHashSet集合概述和特点

08_TreeSet集合概述和特点

3.7、TreeSet集合概述和特点

API-TreeSet

API-NavigableSet

API-Comparable 自然排序接口

API-Comparator

09_自然排序Comparable的使用

3.8、自然排序Comparable的使用

10_比较器排序Comparator的使用

3.9、比较器排序Comparator的使用

11_成绩排序

案例:成绩排序

1、比较器排序Comparator

2、自然排序Comparable

12_不重复的随机数

案例:不重复的随机数

13_泛型概述和好处

4.1、泛型概述

14_泛型类

4.2、泛型类

15_泛型方法

4.3、泛型方法

16_泛型接口

4.4、泛型接口

17_类型通配符

4.5、类型通配符

18_可变参数

4.6、可变参数

19_可变参数的使用

4.7、可变参数的使用

1、public static List asList​(T... a)

2、public static List of​(E... elements)

3、public static Set of​(E... elements)


01_Set集合概述和特点

3.1、Set集合概述和特点

Set集合的特点

  • 元素存取无序
  • 不包含重复元素的集合(不能存储重复元素)
  • 没有索引,不能使用普通for循环遍历,只能通过迭代器或增强for循环遍历

  • public interface Set<E>
    extends Collection<E>

Set是接口,不能直接实例化 --> 实现类HashSet

Set集合的基本使用:Set集合练习 存储字符串并遍历【 HashSet:对集合的迭代顺序不作任何保证】

02_哈希值

3.2、哈希值

哈希值简介

  • 是JDK根据对象的地址或者字符串或者数字算出来的int类型的数值

如何获取哈希值(Object类中,有一个方法可以获取对象的哈希码

  • Object类中的 public int hashCode():返回对象的哈希码值

哈希值的特点

  • 同一个对象多次调用hashCode()方法返回的哈希值是相同的。
  • 默认情况下,不同对象的哈希值是不同的。而重写hashCode()方法,可以实现让不同对象的哈希值相同。

03_HashSet集合概述和特点

3.3、HashSet集合概述和特点

HashSet集合的特点

  1. 底层数据结构是哈希表。
  2. 对集合的迭代顺序不作任何保证,也就是说:不保证存储和取出的元素顺序一致。
  3. 没有带索引的方法,所以不能使用普通for循环遍历。
  4. 由于是Set集合,所以是不包含重复元素的集合。

HashSet集合练习:HashSet集合的基本使用---存储字符串并遍历

04_HashSet集合保证元素唯一性源码分析

3.4、HashSet集合保证元素唯一性源码分析

HashSet集合添加一个元素的过程(HashSet集合保证元素唯一性的图解):

HashSet集合保证元素唯一性的原理

  1. 根据对象的哈希值计算存储位置:如果当前位置没有元素则直接存入;如果当前位置有元素存在,则进入第二步。
  2. 当前元素的元素和已经存在的元素比较哈希值:如果哈希值不同,则将当前元素进行存储;如果哈希值相同,则进入第三步。
  3. 通过equals()方法比较两个元素的内容:如果内容不相同,则将当前元素进行存储;如果内容相同,则不存储当前元素。

 HashSet集合存储元素:

  • 要保证元素唯一性,需要重写hashCode()equal()

05_常见数据结构之哈希表

3.5、常见数据结构之哈希表

哈希表

  • JDK8之前,底层采用数组+链表实现,可以说是一个元素为链表的数组。
  • JDK8以后,在长度比较长的时候,底层实现了优化。

存储元素:先比较哈希值,哈希值相同的时候,再比较内容。

06_HashSet集合存储学生对象并遍历

案例:HashSet集合存储学生对象并遍历

// 重复存储学生对象!保证元素唯一性:HashSet底层数据结构是哈希表,哈希表依赖于2个方法
// hashCode()与equals() -> 学生类 重写 hashCode()与equals()

自动生成hashCode()与equals()方法:快捷键 Alt + Insert

   

   

07_LinkedHashSet集合概述和特点

3.6、LinkedHashSet集合概述和特点

LinkedHashSet集合特点

  1. 哈希表和链表实现的Set接口,具有可预测的迭代次序。
  2. 由链表保证元素有序,也就是说元素的存储和取出顺序是一致的。
  3. 由哈希表保证元素唯一,也就是说没有重复的元素。

LinkedHashSet集合基本使用:LinkedHashSet集合练习——存储字符串并遍历

08_TreeSet集合概述和特点

3.7、TreeSet集合概述和特点

TreeSet集合概述and特点

  • 元素有序,这里的顺序不是指存储和取出的顺序,而是按照一定的规则进行排序,具体排序方式取决于构造方法。

      TreeSet():根据其元素的自然排序进行排序

      TreeSet(Comparator comparator) :根据指定的比较器进行排序

  • 没有带索引的方法,所以不能使用普通for循环遍历。
  • 由于是Set集合,所以不包含重复元素的集合。

API-TreeSet

API-NavigableSet

API-Comparable 自然排序接口

API-Comparator

TreeSet集合基本使用:TreeSet集合练习——存储整数并遍历

09_自然排序Comparable的使用

3.8、自然排序Comparable的使用

案例需求

  • 存储学生对象并遍历,创建TreeSet集合使用无参构造方法
  • 要求:按照年龄从小到大排序,年龄相同时,按照姓名的字母顺序排序。

实现步骤(结论)

  • 用TreeSet集合存储自定义对象,无参构造方法使用的是自然排序对元素进行排序的。
  • 自然排序,就是让元素所属的类实现Comparable接口,重写compareTo(T o)方法。
  • 重写方法时,一定要注意排序规则必须按照要求的主要条件和次要条件来写。

类转换异常:学生类 不能 转成 自然排序接口。 

如果要做“自然排序”,需要让类实现Comparable接口,重写接口的compareTo()方法。

字符串本身,可以进行比较排序。

10_比较器排序Comparator的使用

3.9、比较器排序Comparator的使用

案例需求

  • 存储学生对象并遍历,创建TreeSet集合使用带参构造方法
  • 要求:按照年龄从小到大排序,年龄相同时,按照姓名的字母顺序排序。

实现步骤(结论)

  • 用TreeSet集合存储自定义对象,带参构造方法使用的是比较器排序对元素进行排序的。
  • 比较器排序,就是让集合构造方法接收Comparator的实现类对象,重写compare(T o1,T o2)方法。
  • 重写方法时,一定要注意排序规则必须按照要求的主要条件和次要条件来写。

第3个构造方法:需要 接口的实现类对象。匿名内部类方式,较为简单。

11_成绩排序

案例:成绩排序

1、比较器排序Comparator

2、自然排序Comparable

12_不重复的随机数

案例:不重复的随机数

13_泛型概述和好处

4.1、泛型概述

泛型概述

是JDK5中引入的特性,它提供了编译时类型安全检测机制,该机制允许在编译时检测到非法的类型。

它的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。

一提到参数,最熟悉的就是定义方法时有形参,然后调用此方法时传递实参。那么参数化类型怎么理解呢?顾名思义,就是将类型由原来的具体的类型参数化,然后在使用/调用时传入具体的类型。这种参数类型可以用在类、方法和接口中,分别被称为泛型类、泛型方法、泛型接口。

泛型定义格式:

  • <类型>:指定一种类型的格式。这里的类型可以看成是形参。
  • <类型1, 类型2, ...>:指定多种类型的格式,多种类型之间用逗号隔开。这里的类型可以看成是形参。
  • 将来具体调用时候给定的类型可以看成是实参,并且实参的类型只能是引用数据类型。

泛型的好处

  • 把运行时期的问题提前到了编译期间。
  • 避免了强制类型转换。 

当没有指定集合中元素类型的时候,默认是Object类型:因为 泛型默认是引用类型,Object可以代表所有的引用类型。

14_泛型类

4.2、泛型类

15_泛型方法

4.3、泛型方法

方法名相同,参数列表不同:方法重载!

方法调用,需要相对应,过于麻烦。--> 使用“泛型类”进行改进,只需要一个方法。

调用方法,需要明确数据类型,过于麻烦。--> 创建对象的时候,不明确数据类型,在调用方法的时候,明确数据类型。

泛型方法:接收任意泛型的数据类型。

16_泛型接口

4.4、泛型接口

接口不能直接实例化。

参照ArrayList类(泛型类):

17_类型通配符

4.5、类型通配符

18_可变参数

4.6、可变参数

19_可变参数的使用

4.7、可变参数的使用

Arrays工具类中有一个静态方法:

  • public static <T> List<T> asList​(T... a)【public static List asList(T... a)】:返回由指定数组支持的固定大小的列表
  • 返回的集合不能做增删操作,可以做修改操作

 List接口中有一个静态方法:

  • public static List of(E... elements)【public static <E> List<E> of​(E... elements)】:返回包含任意数量元素的不可变列表
  • 返回的集合不能做增删改操作

Set接口中有一个静态方法:

  • public static Set of(E... elements)【public static <E> Set<E> of​(E... elements)】:返回一个包含任意数量元素的不可变集合
  • 在给元素的时候,不能给重复的元素
  • 返回的集合不能做增删操作,没有修改的方法

1、public static <T> List<T> asList​(T... a)

2、public static <E> List<E> of​(E... elements)

3、public static <E> Set<E> of​(E... elements)

set无带索引的方法。

猜你喜欢

转载自blog.csdn.net/weixin_44949135/article/details/107891346