共计 1620 个字符,预计需要花费 5 分钟才能阅读完成。
Set集合
概述
Set是Java中的一种继承自Collection接口,不允许包含重复元素。具体的实现类有HashSet和TreeSet。只能存放引用类型。
常用方法
1. 添加元素
add(E e)//添加一个元素
addAll(Collection<? extends E> c)`//合并两个集合
2. 清空集合
clear()
3. 查询是否包含某一个元素
contains(Object o)
4.判断集合是否是空
isEmpty()
5. 删除元素
remove(Object o) //删除一个元素
removeAll(Collection<?> c) //删除集合c里所包含的元素
retainAll(Collection<?> c) //保留集合c里所包含的元素,其他删除
常用的实现类
1. HashSet
概述
- 底层数据结构是哈希表,不保证顺序,是不同步的。
- 允许存储
null
2. TreeSet
概述
-
底层数据结构是基于红黑树(一种自平衡的二叉搜索树)实现的,这意味着它会对元素进行排序,并且元素的插入、删除和查找操作通常具有对数时间复杂度$O(log n)$。
-
不允许存储
null
自然排序
自然排序要求TreeSet集合中存储的元素所在的类必须实现Comparable接口,并重写comoareTo()方法,然后TreeSet集合就会对该类型使用compareTo()方法进行比较,并默认进行升序排序
自定义排序
创建TreeSet时,向其中传入已经重写Comparator中方法的对象, Comparator是一个接口。
TreeSet<Student> se1 = new TreeSet<Student>(new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
if (o1.getName().length() == o2.getName().length()) {
int nameComparison = o1.getName().compareTo(o2.getName());
if (nameComparison == 0) {
return Integer.compare(o1.getAge(), o2.getAge());
}
return nameComparison;
}
return Integer.compare(o1.getName().length(), o2.getName().length());
}
});
共有特点
- 通过
hashCode()来判断是否已经有元素重复,所以元素的hashCode()和equals()一定要重写。(详细见注意1.) - 两者都不是线程安全的(什么是线程不安全,见注意2)
注意
1. set集合所的元素的equals()和hashCode()方法通常都要重写的原因
Object类提供的equals()方法默认是用==来进行比较的,也就是说只有两个对象是同一个对象时,才能返回相等的结果。而在实际的业务当中,我们通常要判断的是两个的对象的内容是否相同。所以Object类中equals()方法的默认实现是没有实用价值的,所以通常都要重写。
因为hashCode()与equals()具有联动关系,所以也要一起重写。
2.什么是线程安全
概述
线程安全是指在多线程环境下,每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的。
为什么会导致线程不安全
-
不满足原子性:一个或者多个操作在 CPU 执行的过程中被中断
即一个操作或者多个操作,要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行。原子性就像数据库里面的事务一样,他们是一个团队,同生共死。
-
不满足可见性:一个线程对共享变量的修改,另外一个线程不能立刻看到
可见性是指当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看得到修改的值。
-
不满足有序性:程序执行的顺序没有按照代码的先后顺序执行
即程序执行的顺序按照代码的先后顺序执行