java容器类 set_java容器类3:set/HastSet/MapSet深入解读

介绍

Set:集合,是一个不包含重复数据的集合。(A collection that contains no duplicate elements. )

set中最多包含一个null元素,否者包含了两个相同的元素,不符合定义。

上一篇学习了Java中的容器类的一些基础接口,以及Collection接口三大分支中的List分支(ArrayList以及LinkedList)。这一篇文章将讲解Collection三大分支(List、Set、Queue)中的Set分支,以及衍生出来的子类。

Set接口的总的集成关系如下图:

bc185b3ab1294d675cdd6258958ed5ec.png

Set接口

public interface Set extends Collection

查看Set的源码可以发现,Set中的接口函数和Collection完全相同,并没有添加任何新的接口。只是子类在实现这些接口的时候需要考虑,Set中不能有重复的元素这一原则。接口中的函数及描述可查看上一篇博客。

AbstractSet抽象类

和AbstractList及AbstractCollection的作用相似,AbstractSet类作为一个抽象类,实现了Set接口中的部分函数,减少后续Set子类的实现工作。

public abstract class AbstractSet extends AbstractCollection implements Set

具体该抽象类实现了Set中的如下几个接口:

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;

}

}

hashCode():Set的hash值等于将Set中所有元素的hash值相加,这就保证了if(set1.equals(set2)) 那么set1.hashCode()== set2.hashCode()。

public int hashCode() {

int h = 0;

Iterator i = iterator();

while (i.hasNext()) {

E obj = i.next();

if (obj != null)

h += obj.hashCode();

}

return h;

}

removeAll(): 移除c与当前Set的交集,返回值代表是否有元素从当前Set中移除,交集为空返回false否则返回true。

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;

}

SortedSet

public interface SortedSet extends Set

public interface SortedSet extends Set {//经过某种排序的set JDK1.7 java.util

Comparator super E> comparator();//返回对此 set中的元素进行排序的比较器

SortedSet subSet(E fromElement, E toElement);//返回此 set的部分视图,其元素从 fromElement(包括)到 toElement(不包括)。(

SortedSet headSet(E toElement);//返回此 set 的部分视图,其元素严格小于 toElement

SortedSet tailSet(E fromElement);//返回此 set的部分视图,其元素大于等于 fromElement

E first();//set中第一个元素

E last();//set中最后一个元素

}

NavigableSet

public interface NavigableSet extends SortedSet {//扩展的 SortedSet,具有了搜索匹配元素方法 JDK1.7 java.util

E lower(E e);//返回此 set中小于给定元素的最大元素

E floor(E e);//返回此 set中小于等于给定元素的最大元素

E ceiling(E e);//返回此 set中大于等于给定元素的最小元素

E higher(E e);//返回此 set中大于给定元素的最小元素

E pollFirst();//获取并移除第一个元素

E pollLast();//获取并移除最后一个元素

Iterator iterator();//以升序返回在此set的元素上进行迭代的迭代器

NavigableSet descendingSet();//返回此 set中所包含元素的逆序视图

Iterator descendingIterator();//以降序返回在此 set的元素上进行迭代的迭代器。效果等同于 descendingSet().iterator()。

//返回此 set 的部分视图,其元素范围从 fromElement 到 toElement

NavigableSet subSet(E fromElement, boolean fromInclusive, E toElement, boolean toInclusive);

//返回此 set的部分视图,其元素小于(或等于,如果 inclusive 为 true)toElement

NavigableSet headSet(E toElement, boolean inclusive);

//返回此 set的部分视图,其元素大于(或等于,如果 inclusive 为 true)fromElement

NavigableSet tailSet(E fromElement, boolean inclusive);

//返回此 set 的部分视图,其元素从 fromElement(包括)到 toElement(不包括)。

SortedSet subSet(E fromElement, E toElement);

//返回此 set的部分视图,其元素严格小于 toElement

SortedSet headSet(E toElement);

//返回此 set的部分视图,其元素大于等于 fromElement

SortedSet tailSet(E fromElement);

}

HashSet

public class HashSet extends AbstractSetimplements Set, Cloneable, java.io.Serializable

阅读HashSet的源码,其实很简单,就是在里面维护了一个 HashMap类型的成员变量,然后抽象出了几个增删改查的方法。需要深入了解的话可以阅读:java容器类2:Map及HashMap深入解读

这里有个疑问,HashMap是存放键值对的,而HashSet是存放一组数据的,为什么可以用HashMap保存set数据?

HashMap中的keySet()函数返回的就是一个 Set类型的数据(不能有重复的key值),所以HashSet将Set数组全部存放在HashMap的keySet中,value值全部用默认的一个Object类型的常量表示。

HashSet中的add()函数可以看出

public boolean add(E e) {

return map.put(e, PRESENT)==null;

}

TreeSet

TreeSet的继承关系如下,看上去还挺复杂

2d4994ea7225428b23a11df529e1451f.png

正如TreeSet继承自SortSet一样,TreeSet中存储了排序的数组(每个元素值不能有重复的元素)。

同HashSet实现方法相同,里面维护了一个map(NavigableMap类型)类型的成员变量,来保证所有数据是有序的。map里面的keySet字段可以保存TreeSet的所有值。

TreeSet中的方法都是基于NavigableMap的增删改查操作,这里不详细分析。

参考:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值