1. set
1 概述
无序,不可重复 添加顺序和取出顺序不一定一致
Set --> SortedSet–>TreeSet:底层是红黑树,要添加的元素必须按照某个规则进行排序
2 TreeSet 排序
比较器有两种
1. java.lang.Comparable接口,并实现compareTo()方法
2. java.util.Comparator 比较器类
数字 按照升序排序
字符 按照ASCII码排序(每位比较)
时间 默认自然日期(今天、明天、后天)
String Interger Date 都实现了Comparable接口,并实现了compareTo()方法,而往 treeSet中添加数据的时候,会自动调用compareTo()对象。当是自定义类型的时候,就用不了,需要实现Comparable接口,并实现compareTo()方法
2.1 Comparable
如果我们的自定义类型想要放到treeSet中,必须实现Comparable接口,否则就无法使用treeSet进行数据保存
class User implements Comparable{
int age;
@Override
public String toString() {
return "User [age=" + age + "]";
}
public User(int age) {
this.age = age;
}
@Override
public int compareTo(Object o) {
// this 是要要添加的元素 , o 是集合中的每一个元素
// 返回值为0 , 说明相等, 就不添加
// 返回小于0 的, 说明要添加的元素比集合中的元素小,就放到前面
// 返回大于0的,说明要添加的元素比集合中的元素大,就放到后面
if (o instanceof User) {
User user = (User) o;
// 升序
// return this.age - user.age;
// 降序
return user.age - this.age;
}
return -1;
}
}
2.2 Comparator
1.应用场景
要保存数字,Integer默认是升序,无法修改源码。这时就可以使用Comparator,通过TreeMap源码发现,优先级高于Comparable。
当自定义类型,需要排序,默认使用comparable,再使用comparator进行扩展。
总之:当其他类无法满足排序规则的时候,都可以使用Comparator进行扩展排序。
2. List 排序
元素必须实现Comparator接口(Integer中实现了Comparable,如果不满足需求再Comparator)
Collections.sort(arrayList);
Sysout.out.println(arrayList);
sort( , )方法有一个重载,接收comparator
一般自定义排序复用性不高,为了简便,可以使用匿名内部类
// 匿名内部类写法
TreeSet treeSet = new TreeSet( new Comparator() {
@Override
public int compare(Object o1, Object o2) {
// o1是要添加的元素,o2是集合中的元素
Integer i1 = (Integer) o1;
Integer i2 = (Integer) o2;
// i1-i2是升序, i2-i1是降序
return i2 - i1;
}
} );
2.3 树
2.3.1 二叉查找树
类似于二分法查找,查询效率快
左叶子<根节点<右叶子
但是二叉树也有问题,一直添加比根结点小或大的,虽然符合特性但是性能大打折扣,几乎变成了线性
2.3.2 红黑树
解决二叉查找树不平衡的问题
1.结点是红色或者黑色
2.根结点一定是黑色
3.每个子节点都是黑色的空节点
4.每个红结点的两个子节点都是黑色()
5.从任何结点到每一个子节点都有相同数量的黑结点
3. HashSet
散列表:数组中保存的链表
只能添加和删除,无法查找和修改
原因:底层就是HashMap的key部分,屏蔽了Hashmap的value
而Hushmap底层是散列表
添加过程:
1.根据key生成hush的值
2.根据生成的hush值hush值,通过hush算法得到数组下标
3.调用key的equals方法,和数组中对应的链表的每一个结点进行比较
4.如果不存在,就添加进去,不存在就不添加
5.java8开始引入了红黑树,如果链表个数 大于等于9,就转换从红黑树