文章目录
前言
本文章帮助大家对Set
接口的理解。
一、概述
Set
意为集合(无特殊说明,本文章“集合”指Set
)。顾名思义,就是同一类对象(元素)的集合体。它继承于Collection
接口,但不能有重复的元素,且最多只能有一个空元素。只要是需要使用符合数学集合特性的,建议实现此接口。参考Collection
接口。
of
、copyOf
静态方法可以创建不可修改的集合,即不能增加、删除其元素。但若元素本身是可修改的,其修改会导致不一致的行为。其元素不能为空。其元素不能重复。其迭代顺序是不确定的。它属于值类型。
二、源码理解
包
package java.util;
import java.util.Set;
使用Set
接口时,需引入此包。
Set接口
public interface Set<E> extends Collection<E> { /*...*/ }
使用接口时传入泛型E
,为集合元素的类型。继承了Collection
接口,使集合具有Collection
集合的表现。
注意:若元素是可修改对象,其修改会导致不确定的行为,其中一种情况就是将其实现类对象作为其元素。
注意:除Collection
规定外,还要求其实现类遵守如此规定:其构造函数创建的集合不能包含重复的元素。
Set方法
size
int size();
重写Collection
接口的int size()
方法,参考Collection.size
方法。
返回元素个数。若集合包含元素个数大于Integer.MAX_VALUE
,则返回Integer.MAX_VALUE
。
isEmpty
boolean isEmpty();
重写Collection
接口的boolean isEmpty()
方法,参考Collection.isEmpty
方法。
判断集合是否为空。
equals
boolean equals(Object o);
重写Collection
类的boolean equals(Object obj)
方法,参考Collection.equals
方法。
判断集合和对象o
是否相同/相等。
注意:要返回true
的一些前提是它们都是集合,元素数量一样,两个集合互相包含对方的元素。
hashCode
int hashCode();
重写Collection
类的int hashCode()
方法,参考Collection.hashCode
方法。
返回此集合的哈希码。它定义为所有元素的哈希码的和(不同实现不一定是返回其和)。
iterator
Iterator<E> iterator();
重点:重写Collection
接口的Iterator<E> iterator()
方法,参考Collection.iterator
方法。
返回遍历元素的迭代器。一般来说对遍历顺序没有要求。
spliterator
default Spliterator<E> spliterator() { return Spliterators.spliterator(this, Spliterator.DISTINCT); }
重写Collection
接口的Spliterator<E> spliterator()
方法,参考Collection.spliterator
方法。
返回覆盖此集合元素的分割迭代器,可用来遍历、分割序列。参考Spliterators.spliterator
方法。default
关键字给出默认实现。
contains
boolean contains(Object o);
重写Collection
接口的boolean contains(Object o)
方法,参考Collection.contains
方法。
判断集合是否包含对象o
。通常认为找到一个元素e
,存在Objects.equals(o, e)
则返回true
。参考Objects.equals
方法。
若对象o
的类型和集合类型不能比较,则抛出ClassCastException
异常(可选);若对象o
为空而集合不允许有空元素,则抛出NullPointerException
异常(可选)。
containsAll
boolean containsAll(Collection<?> c);
重写Collection
接口的boolean containsAll(Collection<?> c)
方法,参考Collection.containsAll
方法。
判断此集合是否包含Collection
集合c
的所有元素。若都包含则返回true
。若c
也是一个集合,则该方法判断c
是否为此集合的子集。
若c
中某元素的类型和此集合类型不能比较,则抛出ClassCastException
异常(可选);若c
中某元素为空而此集合不允许有空元素(可选),或c
为空,则抛出NullPointerException
异常。
add
boolean add(E e);
重写Collection
接口的boolean add(E e)
方法,参考Collection.add
方法。
添加元素e
到此集合中(可选)。若此集合未包含元素e
,返回true
;否则不添加并返回false
。
若实现类不支持add
操作,则抛出UnsupportedOperationException
异常;若因e
的类而不能加入集合中,则抛出ClassCastException
异常;若元素e
为空而集合不允许有空元素,则抛出NullPointerException
异常;若因e
的一些属性而不能加入集合中,则抛出IllegalArgumentException
异常。
addAll
boolean addAll(Collection<? extends E> c);
重写Collection
接口的boolean addAll(Collection<? extends E> c)
方法,参考Collection.addAll
方法。
添加Collection
集合c
的所有元素到此集合中,但保持元素不重复(可选)。若成功添加,返回true
。若c
也是一个集合,则该方法使此集合成为c
和原集合的并集。
若实现类不支持addAll
操作,则抛出UnsupportedOperationException
异常;若因c
中某元素的类而不能加入此集合中,则抛出ClassCastException
异常;若c
中某元素为空而此集合不允许有空元素,或c
为空,则抛出NullPointerException
异常;若因c
中某元素的一些属性而不能加入此集合中,则抛出IllegalArgumentException
异常。
remove
boolean remove(Object o);
重写Collection
接口的boolean remove(Object o)
方法,参考Collection.remove
方法。
从集合中移除一个等于对象o
的元素(若有的话)(可选)。通常认为找到一个元素e
,存在Objects.equals(o, e)
则移除。若成功移除,返回true
。
若对象o
的类型和集合类型不能比较,则抛出ClassCastException
异常(可选);若对象o
为空而集合不允许有空元素,则抛出NullPointerException
异常(可选);若实现类不支持remove
操作,则抛出UnsupportedOperationException
异常。
removeAll
boolean removeAll(Collection<?> c);
重写Collection
接口的boolean removeAll(Collection<?> c)
方法,参考Collection.removeAll
方法。
从此集合中移除Collection
集合c
中的所有元素(有包含的话)(可选)。若成功移除,返回true
。若c
也是一个集合,则该方法使此集合成为原集合和c
的集合差。
若c
中某对象的类型和此集合类型不能比较,则抛出ClassCastException
异常(可选);若c
中某对象为空而此集合不允许有空元素(可选),或c
为空,则抛出NullPointerException
异常;若实现类不支持removeAll
操作,则抛出UnsupportedOperationException
异常。
retainAll
boolean retainAll(Collection<?> c);
重写Collection
接口的boolean retainAll(Collection<?> c)
方法,参考Collection.retainAll
方法。
保留此集合中有包含在Collection
集合c
中的所有元素,即移除其它c
中没有的元素(可选)。若成功移除,返回true
。若c
也是一个集合,则该方法使此集合成为c
和原集合的交集。
若c
中某对象的类型和此集合类型不能比较,则抛出ClassCastException
异常(可选);若c
中某对象为空而此集合不允许有空元素(可选),或c
为空,则抛出NullPointerException
异常;若实现类不支持retainAll
操作,则抛出UnsupportedOperationException
异常。
clear
void clear();
重写Collection
接口的void clear()
方法,参考Collection.clear
方法。
清空集合(可选)。若实现类不支持clear
操作,则抛出UnsupportedOperationException
异常。
toArray
Object[] toArray();
重写Collection
接口的Object[] toArray()
方法,参考Collection.toArray
方法。
返回包含所有元素的对象数组。
注意:若需要集合元素有序(迭代器遍历顺序),那返回数组也应该有相同的顺序。返回的数组新创建了空间,不影响原来的集合。
<T> T[] toArray(T[] a);
重写Collection
接口的<T> T[] toArray(T[] a)
方法,参考Collection.toArray
方法。
传入泛型T
,为返回数组的元素的类型。返回包含所有元素的对象数组。若a
数组大小足够存储集合元素,那元素将存它里面(多余的空间第一个位置设空);否则将创建返回新的数组。
若数组运行时类型不是所有集合元素运行时类型的超类型,则抛出ArrayStoreException
异常;若数组为空,则抛出NullPointerException
异常。
注意:若需要集合元素有序(迭代器遍历顺序),那返回数组也应该有相同的顺序。返回数组的运行时类型是a
的类型。toArray(new Object[0])
功能和toArray()
相同。
of
static <E> Set<E> of() {
return (Set<E>) ImmutableCollections.EMPTY_SET;
}
静态方法,传入泛型E
,为返回集合的元素类型。返回不包含元素的不可修改集合。参考ImmutableCollections
类。
static <E> Set<E> of(E e1) {
return new ImmutableCollections.Set12<>(e1);
}
静态方法,传入泛型E
,为传入值及返回集合的元素类型。返回包含参数元素的不可修改集合。若存在为空的参数,则抛出NullPointerException
异常。
static <E> Set<E> of(E e1, E e2) {
return new ImmutableCollections.Set12<>(e1, e2);
}
静态方法,传入泛型E
,为传入值及返回集合的元素类型。返回包含参数元素的不可修改集合。类似of(E e1)
方法,若参数有重复值,则抛出IllegalArgumentException
异常。
static <E> Set<E> of(E e1, E e2, E e3) {
return ImmutableCollections.SetN(e1, e2, e3);
}
静态方法,传入泛型E
,为传入值及返回集合的元素类型。返回包含参数元素的不可修改集合。类似of(E e1)
方法,若参数有重复值,则抛出IllegalArgumentException
异常。
static <E> Set<E> of(E e1, E e2, E e3, E e4) {
return ImmutableCollections.SetN(e1, e2, e3, e4);
}
静态方法,传入泛型E
,为传入值及返回集合的元素类型。返回包含参数元素的不可修改集合。类似of(E e1)
方法,若参数有重复值,则抛出IllegalArgumentException
异常。
static <E> Set<E> of(E e1, E e2, E e3, E e4, E e5) {
return ImmutableCollections.SetN(e1, e2, e3, e4, e5);
}
静态方法,传入泛型E
,为传入值及返回集合的元素类型。返回包含参数元素的不可修改集合。类似of(E e1)
方法,若参数有重复值,则抛出IllegalArgumentException
异常。
static <E> Set<E> of(E e1, E e2, E e3, E e4, E e5, E e6) {
return ImmutableCollections.SetN(e1, e2, e3, e4, e5, e6);
}
静态方法,传入泛型E
,为传入值及返回集合的元素类型。返回包含参数元素的不可修改集合。类似of(E e1)
方法,若参数有重复值,则抛出IllegalArgumentException
异常。
static <E> Set<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7) {
return ImmutableCollections.SetN(e1, e2, e3, e4, e5, e6, e7);
}
静态方法,传入泛型E
,为传入值及返回集合的元素类型。返回包含参数元素的不可修改集合。类似of(E e1)
方法,若参数有重复值,则抛出IllegalArgumentException
异常。
static <E> Set<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8) {
return ImmutableCollections.SetN(e1, e2, e3, e4, e5, e6, e7, e8);
}
静态方法,传入泛型E
,为传入值及返回集合的元素类型。返回包含参数元素的不可修改集合。类似of(E e1)
方法,若参数有重复值,则抛出IllegalArgumentException
异常。
static <E> Set<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9) {
return ImmutableCollections.SetN(e1, e2, e3, e4, e5, e6, e7, e8, e9);
}
静态方法,传入泛型E
,为传入值及返回集合的元素类型。返回包含参数元素的不可修改集合。类似of(E e1)
方法,若参数有重复值,则抛出IllegalArgumentException
异常。
static <E> Set<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10) {
return ImmutableCollections.SetN(e1, e2, e3, e4, e5, e6, e7, e8, e9, e10);
}
静态方法,传入泛型E
,为传入值及返回集合的元素类型。返回包含参数元素的不可修改集合。类似of(E e1)
方法,若参数有重复值,则抛出IllegalArgumentException
异常。
static <E> Set<E> of(E... elements) {
switch (elements.length) { // implicit null check of elements
case 0:
var set= (Set<E>) ImmutableCollections.EMPTY_SET;
return set;
case 1:
return new ImmutableCollections.Set12<>(elements[0]);
case 2:
return new ImmutableCollections.Set12<>(elements[0], elements[1]);
default:
return ImmutableCollections.SetN(elements);
}
}
静态方法,传入泛型E
,为传入元素及返回集合的元素类型。返回包含参数元素的不可修改集合。若存在为空的参数,或数组参数为空,则抛出NullPointerException
异常,若参数有重复值,则抛出IllegalArgumentException
异常。
注意:...
可变参数可以是多个元素参数或是一个数组参数,但参数是一个数组的话,通过泛型E
来判断此参数应当视为一个元素还是一个数组。如下面例子,array
应视为一个参数,调用的方法是of(E)
:
String[] array = ... ;
Set<String[]> set = Set.<String[]>of(array);
copyOf
static <E> Set<E> copyOf(Collection<? extends E> coll) {
if (coll instanceof ImmutableCollections.AbstractImmutableSet) {
return (Set<E>)coll;
} else {
return (Set<E>)Set.of(new HashSet<>(coll).toArray());
}
}
静态方法,传入泛型E
,为传入Collection
集合元素及返回集合的元素类型。返回包含集合coll
的所有元素的不可修改集合。若coll
中存在重复的元素,则只存其中任意一个到返回集合中。若coll
中存在为空的元素,或集合coll
为空,则抛出NullPointerException
异常。
注意:返回集合通常是Collection
集合参数的复制(使用了HashSet.toArray
进行复制,使用了of
方法包含非空检验。参考HashSet.toArray
方法),原Collection
集合修改不会影响到返回集合,但如果Collection
参数集合是不可修改集合,那么返回集合通常不是它的复制(即返回参数本身(本就有非空检验))。
总结
新人源码理解,望大家多多指点。