Set接口源码理解

35 篇文章 0 订阅
34 篇文章 0 订阅


前言

本文章帮助大家对Set接口的理解。


一、概述

Set意为集合(无特殊说明,本文章“集合”指Set)。顾名思义,就是同一类对象(元素)的集合体。它继承于Collection接口,但不能有重复的元素,且最多只能有一个空元素。只要是需要使用符合数学集合特性的,建议实现此接口。参考Collection接口。

ofcopyOf静态方法可以创建不可修改的集合,即不能增加、删除其元素。但若元素本身是可修改的,其修改会导致不一致的行为。其元素不能为空。其元素不能重复。其迭代顺序是不确定的。它属于值类型

二、源码理解

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参数集合是不可修改集合,那么返回集合通常不是它的复制(即返回参数本身(本就有非空检验))。


总结

新人源码理解,望大家多多指点。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值