文章目录
一、HashSet去重机制
1 HashSet底层实现
底层的实现是HashMap,具有和HashMap的数据结构,数组+链表+红黑树
2 HashSet特点
1.无序,不可重复
2.可只能存一个null值
3.线程不安全
3 HashSet去重
主要是通过hashCode()+equals()的方式辨别添加元素是否已存在,首先是通过add()的参数进行hashCode()运算获取hash值,然后再对(hash值-1)&数组长度获取对应的索引值,如果发现数组索引位置为空,则把新增的元素存放进数组,如果里面有数据则会拿出里面的node链表的头节点进行equals()比较,如果存在则添加不成功,如果node链表头节点的node和新增元素不相等则会去判断该链表是否树化,如果树化则往树里面添加节点,如果以上条件都不满足,则会走遍历node链表,逐一去比较是否存在equals()返回true的节点,如果有则结束,如果没有则往链表末尾进行添加元素,然后再进入树化方法判断是否满足条件树化或数组扩容。
二、TreeSet去重机制
1 TreeSet底层实现
底层的实现是TreeMap,数组+红黑树
2 TreeSet特点
1.有序(并不是指输入元素顺序一定和输出元素顺序一致),不可重复
2.可只能存一个null值
3.默认按照自然排序来排序元素,可自定义比较器实现排序
3 TreeSet去重
有两种途径:走自定义比较器,使用添加元素的类默认实现比较器(如果两者条件都不符合,则添加元素的时候会报类类型转换异常)
- 无参构造器,new TreeSet(),则默认去找String实现的比较器,使用里面的compareTo()方法进行去重(0,1,负数,三种状态判断)
- 比较器参数构造器,new TreeSet(new Comparator() {…}),则走自定义比较器
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
.....
// String实现 Comparable<String>接口
public int compareTo(String anotherString) {
int len1 = value.length;
int len2 = anotherString.value.length;
int lim = Math.min(len1, len2);
char v1[] = value;
char v2[] = anotherString.value;
int k = 0;
while (k < lim) {
char c1 = v1[k];
char c2 = v2[k];
if (c1 != c2) {
return c1 - c2;
}
k++;
}
return len1 - len2;
}
}
// 匿名内部类
TreeSet<String> set = new TreeSet<>(new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return 0;
}
});