JavaSE 进阶 (7) 集合
HashSet-基本使用
HashSet集合概述和特点
HashSet 集合特点
- 底层数据结构是哈希表
- 不能保证存储和取出的顺序完全一致
- 没有带索引的方法,所以不能使用普通 for 循环遍历
- 由于是 Set 集合,所以元素唯一
HashSet集合练习
存储字符串并遍历
|
|
HashSet-哈希值
哈希值(哈希码值): 是 JDK 根据对象的地址或者属性值,算出来的 int 类型的整数
Object 类中有一个方法可以获取对象的哈希值
- public int hashCode(): 根据对象的地址值计算出来的哈希值
一个类没有继承关系的话,默认继承 Object 类
|
|
我们可以对 Object 类中的 hashCode 方法进行重写,重写之后,就是根据对象的属相值来计算哈希值的,此时,对象的哈希值就跟地址值没有任何关系了
|
|
对象的哈希值特点
如果没有重写 hashCode 方法,那么是根据对象的地址值计算出的哈希值
- 同一个对象多次调用 hashCode() 方法,返回的哈希值是相同的
- 不同对象的哈希值是不一样的
如果重写了 hashCode 方法,一般都是通过对象的属性值计算处哈希值
- 如果不同的对象属性值是一样的,那么计算出来的哈希值也是一样的
HashSet-JDK7底层原理解析
常见数据结构之哈希表
哈希表
- JDK8 之前,底层采用数组+链表实现 (不包含jdk8)
- JDK8 以后,底层进行了优化,由数组+链表+红黑树实现 (包含jdk8)
HashSet1.7 版本原理解析
HashSet<String> hs = new HashSet<>();
加载因子决定了集合在什么时候扩容
HashSet-JDK8底层优化
HashSet1.8 底层原理解析
为了防止在4索引处的链表过长,如:100-200个,新存入的元素需要和每个元素相比较,次数过多,影响性能
加入红黑树的目的是为了提高效率
此时,如果有元素要存入4索引,他会按照红黑树规则,小的跟左边比,大的跟右边比,如果一样则不存
总结
- 底层结构:哈希表 (数组、链表、红黑树)
- 当挂在下面的元素过多时,不利于添加,也不利于查询,所以在 JDK8 以后,当链表长度超过 8 时,会自动转换为红黑树
- 存储流程不变
HashSet1.8 版本的存储流程
HashSet-练习
案例:HashSet 集合存储学生对象并遍历
需求:创建一个 HashSet 集合,存储多个学生对象,并进行遍历
要求:学生对象的成员变量值相同,我们就认为是同一个对象
|
|
HsahSet 存放的是不重复的值,但是此时 (xiaohei,23) 重复了,并且存储成功了,这是因为 Student 调用父类 Object 类中的 hsahCode 方法,通过对象的地址值计算出哈希值进行比较,此时哈希值是不同的
要求是: 同姓名,同年龄,就认为是同一个不存
重写 hashCode 方法,根据属相值计算哈希值,哈希值相同,存入相同的位置,再重写 equals 方法,比较属相值,一样则不存
结论: 如果 HashSet 集合要存储自定义对象,那么必须重写 hsahCode 和 equals 方法
HashSet-小结
Set集合小结
HashSet:在存储自定义对象的时候,自定义的对象里必须重写 hashCode 方法和 equals 方法,如果存 String、Integer 等,java 底层已经写好了,直接存就好
TreeSet:排序规则分为自然排序、比较器排序,默认使用的是自然排序,若自然排序不能满足要求,就使用比较器排序
LinkedHashSet
- 概述:LinkedHashSet 是 HashSet 的子类,所以也要求重写 hashCode 和 equals 方法
- 特点:LinkedHashSet 是 Set 家族唯一一个”有序的集合”
Map-基本使用
Map集合概述和使用
单列集合:一次存一个元素
 集合/11.png)
双列集合:一次存两个元素 (一对数据)
 集合/14.png)
Map 集合概述
- Interface Map<K, V> K: 键的数据类型 ; V: 值的数据类型
- 键不能重复,值可以重复
- 键和值是一一对应的,每一个键只能找到自己对应的值
- (键 + 值) 这个整体我们称之为 “键值对” 或者 “键值对对象” ,在 Java 中叫做 “Entry对象”
举例: 学生的学号和姓名
| 学号 | 姓名 |
|---|---|
| 1001 | 小智 |
| 1002 | 小美 |
| 1003 | 大胖 |
创建 Map 集合的对象
- 多态的方式
- 具体的实现类 HashMap
|
|
Map-常用方法
Map集合的基本功能
| 方法名 | 说明 |
|---|---|
| public v put (键 , 值) | 添加(如果集合中没有指定的键,则是添加,如果集合中已经存在了指定的键,则是修改,同时返回修改之前的值) |
| public v remove(键) | 根据键删除键值对元素 (返回被删除的键值对的值) |
| public void clear() | 清空集合中的所有元素 |
| public boolean containsKey(键) | 判断集合中是否包含指定的键 |
| public boolean containsValue(值) | 判断集合中是否包含指定的值 |
| public boolean isEmpty() | 判断集合是否为空 |
| public int size() | 获取集合中 ”键值对” 的个数 |
| public 值 get(键) | 根据键获取值 |
| public Set |
获取所有的键 |
| public Collection |
获取所有的值 |
| public Set<Map.Entry<K,V» entrySet() | 获取所有的键值对 |
|
|
Map-第一种遍历方式
遍历Map集合
小故事:有一个房间,里面有 N 对夫妻,先找到所有的丈夫,询问每一个丈夫,让他们找到自己的妻子
 集合/16.png)
Map集合的获取功能
| 方法名 | 说明 |
|---|---|
| et |
获取所有键的集合 |
| get(Object key) | 根据键获取值 |
|
|