简介
集合,这个概念有点模糊。
广义上来讲,java中的集合是指java.util
包下面的容器类,包括和Collection及Map相关的所有类。
中义上来讲,我们一般说集合特指java集合中的Collection相关的类,不包含Map相关的类。
狭义上来讲,数学上的集合是指不包含重复元素的容器,即集合中不存在两个相同的元素,在java里面对应Set。
具体怎么来理解还是要看上下文环境。
比如,面试别人让你说下java中的集合,这时候肯定是广义上的。
再比如,下面我们讲的把另一个集合中的元素全部添加到Set中,这时候就是中义上的。
HashSet是Set的一种实现方式,底层主要使用HashMap来确保元素不重复。
关于 Collection接口 AND AbstractCollection抽象类
1、Set 接口
1.1、Set 简介
Collection接口是集合类的根接口,它没有具体的实现,但是让其两个儿子Set和List,其中Set中不能包含重复的元素。List是一个有序的集合,可以包含重复的元素,提供了按索引访问的方式。
1.2、源码分析
public interface Set<E> extends Collection<E> {
// 查询操作
int size();
boolean isEmpty();
boolean contains(Object o);
Iterator<E> iterator();
Object[] toArray();
// 修改操作
boolean add(E e);
boolean remove(Object o);
// 批量操作
boolean containsAll(Collection<?> c);
boolean addAll(Collection<? extends E> c);
boolean retainAll(Collection<?> c);
boolean removeAll(Collection<?> c);
void clear();
// 比较和哈希
boolean equals(Object o);
int hashCode();
@Override
default Spliterator<E> spliterator() {
return Spliterators.spliterator(this, Spliterator.DISTINCT);
}
}
2、AbstractSet<E> 抽象类
其实现类非常多
基本和 AbstractCollection 没差,就是重写了 equals、hashCode、removeAll() 方法。
public abstract class AbstractSet<E> extends AbstractCollection<E> implements Set<E> {
protected AbstractSet() {}
// 比较
public boolean equals(Object o) {
// 同一个对象,自然相等
if (o == this)
return true;
// 如果不是同一个父类,则肯定不等
if (!(o instanceof Set))
return false;
Collection<?> c = (Collection<?>) o;
if (c.size() != size()) // 大小不等,则肯定不等
return false;
try {
return containsAll(c);
} catch (ClassCastException unused) {
return false;
} catch (NullPointerException unused) {
return false;
}
}
// hash值,就是将set集合中的所有元素的hash累加
public int hashCode() {
int h = 0;
Iterator<E> i = iterator();
while (i.hasNext()) {
E obj = i.next();
if (obj != null)
h += obj.hashCode();
}
return h;
}
// 删除在集合c中的所有元素
public boolean removeAll(Collection<?> c) {
Objects.requireNonNull(c);
boolean modified = false;
if (size() > c.size()) {
for (Iterator<?> i = c.iterator(); i.hasNext(); )
modified |= remove(i.next());
} else {
for (Iterator<?> i = iterator(); i.hasNext(); ) {
if (c.contains(i.next())) {
i.remove();
modified = true;
}
}
}
return modified;
}
}
3、SorteSet 接口
3.1、SortedSet 简介
sortedSet意为按照对象的比较函数对元素排序,而不是只元素的插入次序,插入顺序则用LinkedHashSet来保存,以Comparator comparator()自然方式排序。
SortedSet的所有元素都必须实现Comparable接口(或者被指定的Comparator接受),并且所有这些元素必须是可相互比较的
3.2、源码
public interface SortedSet<E> extends Set<E> {
// 比较器
Comparator<? super E> comparator();
// 返回中间一个子集
SortedSet<E> subSet(E fromElement, E toElement);
// 返回从头到指定位置的子集
SortedSet<E> headSet(E toElement);
// 返回从自定位置到结尾的子集
SortedSet<E> tailSet(E fromElement);
// 返回第一个元素
E first();
// 返回最后一个元素
E last();
// 返回 可分割迭代器
@Override
default Spliterator<E> spliterator() {
return new Spliterators.IteratorSpliterator<E>(
this, Spliterator.DISTINCT | Spliterator.SORTED | Spliterator.ORDERED) {
@Override
public Comparator<? super E> getComparator() {
return SortedSet.this.comparator();
}
};
}
}
4、几种常用的 Set 的具体实现类
JDK8系列:Set集合 之 LinkedHashSet 源码分析