集合02

本文详细介绍了Java集合框架中的TreeSet和HashSet的使用,包括元素排序原理和Comparator接口的应用。TreeSet依赖Comparable接口进行自动排序,而HashSet利用hashCode和equals确保元素唯一性。此外,讲解了Map接口及其子类HashMap的特点,以及泛型在集合中的作用,强调泛型提高类型安全性和减少类型转换的必要性。
摘要由CSDN通过智能技术生成

集合

1.Collection

1…1排序

1.1.1Comparable

比较器有两种 : 1 元素自身比较器, 2 比较器类
思考 : 为什么字符串,Integer,Date可以排序?
因为都实现了 implements Comparable
使用treeSet在进行数据添加的时候,会自动调用该对象的compareTo()方法和集合内元素进行比较

如果我们想要存储自定义类型怎么办时---->需要实现该接口才行
package Collection;

import java.util.TreeSet;
/**比较器有两种 : 1 元素自身比较器, 2 比较器类

  • 为什么字符串,Integer,Date可以排序?
  • 因为都实现了 implements Comparable
  • 因为使用treeSet在进行数据添加的时候,会自动调用该对象的compareTo()方法
  • 和集合内元素进行比较
  • 如果我们想要存储自定义类型的时候 需要实现该接口就可以
  • @author prisident

*/
public class Collection_09_TreeSet {
public static void main(String[] args) {

TreeSet treeSet = new TreeSet();
User user1 = new User(11);
User user2 = new User(13);
User user3 = new User(6);
treeSet.add(user1);
treeSet.add(user2);
treeSet.add(user3);

// 默认从小到大排序,只需要控制返回值返回发数大小就行
for (Object object : treeSet) {
	System.out.println(object);
}

}
}

// 毕节类User 继承Comparable
class User implements Comparable{
private int age;

public int getAge() {
	return age;
}

public void setAge(int age) {
	this.age = age;
}

public User(int age) {
	super();
	this.age = age;
}

@Override
public String toString() {
	return "User [age=" + age + "]";
}


//重写比较器
@Override
public int compareTo(Object o) {
	

	// o 是集合内对象
	User user = (User) o;
	
	// this 是当前对象
	// 排序
	// 并且 返回值为0 表示 相等,则不添加
	// 返回大于0 的 表示 要添加的元素大,则放到后面
	// 返回小于0 的 表示 要添加的元素小,则放到前面
	//升序
	//return this.age - user.age;
	//降序
	return  user.age - this.age;
	
}

}
添加的时候 会自动调用该对象的compareTo方法,而该方法就在Comparable接口中,所以 必须要实现,否则不能添加到TreeSet中

1.1.2Comparator

treeSet添加的元素必须排序
两种方式 :
1 要添加的元素对应的类实现java.lang.Comparable接口,并实现compareTo方法
2 使用java.util.Comparator比较器类

如果要添加的元素,符合两种比较器(都有) 则 Comparator优先(compare方法)
Comparable : 要添加的元素,实现该接口并覆写compareTo方法
Comparator : 比较器类,常应用 : 比如Integer默认升序,我想降序怎么办? 使用Comparator进行降序排序
如果 添加的元素的类 是我们写的,我们应该使用 Comparable , 因为对扩展开发,其他人还可以使用 Comparator 实现新的排序功能
如果 添加的元素的类 不是我们写的
1 该类有排序(实现了Comparable) 比如Integer,但是 默认排序结果不是我们想要的,那么我们可以使用Comparator进行调整排序,因为优先级高
2 如果该类没有实现排序(没有实现Comparable), 这时候我们需要使用Comparator进行排序,因为我们不可能去改变人家类的源码
在这里插入图片描述
双列比较
在这里插入图片描述

1.1.3Collections

List排序,想要排序 元素必须实现 Comparable接口
在这里插入图片描述
如果 自身 的Comparable实现的排序方式,不是我们想要的,或者 没有实现Comparable排序

那么我们应该如何对list排序呢?

在这里插入图片描述

1.4总结

如果 添加的元素的类 是我们写的,我们应该使用 Comparable , 因为对扩展开发,其他人还可以使用 Comparator 实现新的排序功能
如果 添加的元素的类 不是我们写的
1 该类有排序(实现了Comparable) 比如Integer,但是 默认排序结果不是我们想要的,那么我们可以使用Comparator进行调整排序,因为优先级高
2 如果该类没有实现排序(没有实现Comparable), 这时候我们需要使用Comparator进行排序,因为我们不可能去改变人家类的源码

1.2Set

1.21TreeSet

TreeSet : 元素必须有序,添加的元素会按照某种规则自动排序
想要使用TreeSet,元素必须要排序
数字 : 默认从小到大
字符串 : 默认比较每位ASCII码
日期 : 默认比较自然日期 昨天-今天-明天

在这里插入图片描述
在这里插入图片描述

1.2.2HashSet
1.2.2.1散列表

hash算法 : 是一种安全的加密算法,把不定长的值改变为定长值,并不能保证唯一性

散列表 : 数组中 保存链表(单向链表),并且链表节点内有四个属性
1 key 2 value 3 next 4 hash
散列表是一种数据结构,不过java中屏蔽了,直接以封装的形式封装到了HashSet, HashMap 和HashTable中
hash算法在java中 就是指 hashCode函数及重写
哈希的目的 就是为了查询快,因为hash是一个固定的值

1 hash过程
拿到对象,调用对象自身的hashCode()方法,然后进行hash算法,得到数组下标,把值保存到对应的数组中,
Set特性 : 无序 , 不可重复(hashCode和equals)

2 HashSet 和 HashMap
HashSet 就是HashMap的封装,本质就是一个HashMap
默认初始化容量 都是 16
封装之后 HashSet把value值屏蔽了,只能操作key,所以在使用set添加的时候,只需要传入key即可

3 添加过程
1 使用添加的键值对中的key,调用key的hashCode方法,生成hash值,进行hash算法得到数组下标,判断该下标上是否有元素,如果没有,把该键值对 保存到该数组中即可
2 如果该数组中有对象,则调用key的equals方法和数组中的元素进行比较,如果相等则key不添加,value值覆盖

3 如果不相等,就把该 对象的 添加到已有元素的next属性,形成链表
4 如果添加的时候 就已经是链表了,则需要用key和链表中所有的元素key进行比较是否相等在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

HashSet 的使用

因为散列表中 需要使用hashCode和equals来表示对象的唯一性
所以 在进行添加自定义类型的时候,需要考虑 按需求重新hashCode和equals方法
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2Map

2.1概述

Map : 无序 可重复
value可重复, key不可重复
Map和 集合的操作 基本都是一样的
Map和 集合的操作 基本都是一样的
常用方法
Object put(Object key,Object value) : 向map中添加键值对
void clear() : 清空
int size() : 添加的个数

boolean isEmpty() : 判断是否为空
Object get(Object key) : 根据key 获取value
Collection values() : 获取map中的所有value值,以集合形式返回
booelan containsKey(Object key) : 判断是否包含某个key
booelan containsValue(Object value) : 判断是否包含某个value

Set keySet() : 获取map中的所有key,以Set集合形式返回
Set entrySet() : 返回map中的键值对映射(key=value),以Set集合形式返回
V remove(Object key) : 根据key删除指定映射关系,返回value值
map不能直接遍历,可以通过keySet 等方法进行间接遍历

Map用于保存具有映射关系的数据,因此Map集合里保存两组值。

  1. 一组值用于保存key,一组值用于保存value
  2. key~value之间存在单向一对一关系,通过指定key可以找到唯一的value值
  3. key和value都可以是任何引用类型对象
  4. 允许存在value为null,但是只允许存在一个key为null

2.2常用方法

在这里插入图片描述

2.3HashMap

在这里插入图片描述
在这里插入图片描述

2.4扩展之Properties

特殊的Map : 强制规定键和值都必须是字符串
java.util.Properties
在这里插入图片描述

2.5SortedMap

SortedMap是接口,子实现了是TreeMap,元素必须有序,会按照某个规定进行排序
实现排序的原因
1 被添加的元素,实现了Comparable接口
2 按照需求,编写一个比较器类,该比较器类必须实现Comparator接口

treeMap是靠 compareTo方法决定是否唯一,而 get()方法 是根据key调用compareTo方法和每个key进行比较,返回0,说明相等,就获取value
在这里插入图片描述

.3泛型

3.1概述

类型检查 : 编译过程中,检查数据类型是否匹配
什么是泛型 : 集合就跟数组一样,都是只能放同一种数据类型的,那么为什么集合中什么都能放呢?
Object , 元素都向上转型了,但是这样虽然能够存储任意类型,但是使用起来就不方便了
比如我现在要存储学生成绩,不要存储其他类型,只要保存小数即可,如果我们还是要Object的话,那么取出数据之后一定要向下转型才能使用

而引入泛型之后,我们可以指定存储的类型,那么编译器在编译阶段,就会检查添加的数据的类型是否匹配,不匹配就报错
泛型只能是引用数据局类型,不能是基本数据类型

优点 : 统一了数据类型,减少数据类型转换
缺点 : 只能存储单一类型的元素
就是在集合声明的时候指定了该集合的数据类型,指明了类型之后,再向集合中添加数据的时候,编译器就会对数据类型进行校验

虽然指定了泛型,但是 存进去的元素 还是会发生向上转型为Object类型
只是 取出来的时候,可以直接获取元素类型,不需要强制类型转换
泛型常用的标记 T , ? , E , K , V

T type : 表示是一个java类型
E Element : 元素,表示集合或者数组中的数据
KV : key,value 键值对
? : 表示一个不确定的类型
如果 人家规定了泛型,可以让我们指定数据类型,如果我们不指定的情况下,默认是Object

3.2使用

不使用泛型
什么也能放
但是获取使用的时候,需要向下 转型 比较麻烦

在这里插入图片描述

使用泛型之后

在这里插入图片描述

在这里插入图片描述

3.3自定义泛型

在这里插入图片描述

面试题

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值