今天来学习一下set家族。
一、Set与Map的关系
Set 和 Map是java中的两大类容器。
其中map的以一种键值对存在的数据。而Set是一种类型数据的集合。对于Map来说是集合中的key不能够重复,而对于Set来说则是其中的内容不能够重复。
所以从上面我们可以知道其实Map和Set是有一定的相同之处的。
我们都知道一个·Map是由Key - values来组成的,而其中如果我们把values去除掉的话,那么剩下的key是不是构成了一个类似于Set一样的东西。所以说,其实Map和Set的实现其实是类似的。区别在于Set中的每一个元素是一个对象。而Map中的每一个元素是由两个对象组成的组合体组合而成的。
同样,下面来了解一下Set整体的结构
二、Set接口
public interface Set<E> extends Collection<E>
set接口简单继承于Collection接口,因为其中并不需要像Map一样有key和value的绑定,所以其内部只是定义了一些set相关的方法。
三、SortedSet,Navigable接口
sortedSet和NaviagbleSet这两个接口和SortedMap, NaviagbleMap差不多。
四、AbstractSet
public abstract class AbstractSet<E> extends AbstractCollection<E> implements Set<E>
主要实现了equal,hashCode,removeAll的几个方法:
五、HashSet
public class HashSet<E>
extends AbstractSet<E>
implements Set<E>, Cloneable, java.io.Serializable
{
static final long serialVersionUID = -5024744406713321676L;
private transient HashMap<E,Object> map;
// Dummy value to associate with an Object in the backing Map
private static final Object PRESENT = new Object();
我们可以看到HashSet的代码中有一个HashMap,实际上hashSet中的所以操作就是在对于这个hashMap进行的所有操作。而对于hashSet来说使用的只是HashMap中的key域。那么其values域呢?
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
values域都指向PRESENT的一个static final Object。这样就能够更好地节省内存了。
六、TreeSet
public class TreeSet<E> extends AbstractSet<E>
implements NavigableSet<E>, Cloneable, java.io.Serializable
{
/**
* The backing map.
*/
private transient NavigableMap<E,Object> m;
// Dummy value to associate with an Object in the backing Map
private static final Object PRESENT = new Object();
从TreeSet的部分代码来看,TreeSet的实现方式和HashSet的实现方式差不多。都是里面有一个Map,只不过对于HashSet其中有一个HashMap,而TreeSet其中有一个NavigableMap而已。