AbstractCollection中的方法已经在《java数据结构与并发之--List(基础篇)》里已经做过了介绍,已经实现了Collection接口方法,而Set接口本身没有特殊的方法需要继承,在AbstractSet中只重写了 hashCode 和 equals 方法,另外根据Set本身的特征对removeAll方法进行重写来可能性的提高性能。同时值得注意的是,AbstractSet中并没有iterator()的方法进行实现,也没有扩展出特殊的iterator方法。

        HashSet 和 LinkedHashSet 是我们经常会用到的常用的Set的实现类。我们先看一下HashSet,打开HashSet源码你会第一眼看到的就是 这样两个实例变量:

private transient HashMap<E,Object> map;

    // Dummy value to associate with an Object in the backing Map
    private static final Object PRESENT = new Object();
   private transient HashMap<E,Object> map;

    // Dummy value to associate with an Object in the backing Map
    private static final Object PRESENT = new Object();

AbstractSet,这个在具体讲解到 Map 数据结构时再详细讲解),只有以下构造方法:

/**
     * Constructs a new, empty linked hash set.  (This package private
     * constructor is only used by LinkedHashSet.) The backing
     * HashMap instance is a LinkedHashMap with the specified initial
     * capacity and the specified load factor.
     *
     * @param      initialCapacity   the initial capacity of the hash map
     * @param      loadFactor        the load factor of the hash map
     * @param      dummy             ignored (distinguishes this
     *             constructor from other int, float constructor.)
     * @throws     IllegalArgumentException if the initial capacity is less
     *             than zero, or if the load factor is nonpositive
     */
    HashSet(int initialCapacity, float loadFactor, boolean dummy) {
	map = new LinkedHashMap<E,Object>(initialCapacity, loadFactor);
    }
    /**
     * Constructs a new, empty linked hash set.  (This package private
     * constructor is only used by LinkedHashSet.) The backing
     * HashMap instance is a LinkedHashMap with the specified initial
     * capacity and the specified load factor.
     *
     * @param      initialCapacity   the initial capacity of the hash map
     * @param      loadFactor        the load factor of the hash map
     * @param      dummy             ignored (distinguishes this
     *             constructor from other int, float constructor.)
     * @throws     IllegalArgumentException if the initial capacity is less
     *             than zero, or if the load factor is nonpositive
     */
    HashSet(int initialCapacity, float loadFactor, boolean dummy) {
	map = new LinkedHashMap<E,Object>(initialCapacity, loadFactor);
    }


        HashSet的内容就是这些,我们来看一下LinkedHashSet:(没有任何的特殊方法,只利用了我们上面说道的调用 LinkedHashMap 的特殊构造方法修改重写所有的HashSet构造方法,让所有的方法都走了 LinkedHashMap的实现。)

public class LinkedHashSet<E>
    extends HashSet<E>
    implements Set<E>, Cloneable, java.io.Serializable {

    private static final long serialVersionUID = -2851667679971038690L;

    /**
     * Constructs a new, empty linked hash set with the specified initial
     * capacity and load factor.
     *
     * @param      initialCapacity the initial capacity of the linked hash set
     * @param      loadFactor      the load factor of the linked hash set
     * @throws     IllegalArgumentException  if the initial capacity is less
     *               than zero, or if the load factor is nonpositive
     */
    public LinkedHashSet(int initialCapacity, float loadFactor) {
        super(initialCapacity, loadFactor, true);
    }

    /**
     * Constructs a new, empty linked hash set with the specified initial
     * capacity and the default load factor (0.75).
     *
     * @param   initialCapacity   the initial capacity of the LinkedHashSet
     * @throws  IllegalArgumentException if the initial capacity is less
     *              than zero
     */
    public LinkedHashSet(int initialCapacity) {
        super(initialCapacity, .75f, true);
    }

    /**
     * Constructs a new, empty linked hash set with the default initial
     * capacity (16) and load factor (0.75).
     */
    public LinkedHashSet() {
        super(16, .75f, true);
    }

    /**
     * Constructs a new linked hash set with the same elements as the
     * specified collection.  The linked hash set is created with an initial
     * capacity sufficient to hold the elements in the specified collection
     * and the default load factor (0.75).
     *
     * @param c  the collection whose elements are to be placed into
     *           this set
     * @throws NullPointerException if the specified collection is null
     */
    public LinkedHashSet(Collection<? extends E> c) {
        super(Math.max(2*c.size(), 11), .75f, true);
        addAll(c);
    }
}
public class LinkedHashSet<E>
    extends HashSet<E>
    implements Set<E>, Cloneable, java.io.Serializable {

    private static final long serialVersionUID = -2851667679971038690L;

    /**
     * Constructs a new, empty linked hash set with the specified initial
     * capacity and load factor.
     *
     * @param      initialCapacity the initial capacity of the linked hash set
     * @param      loadFactor      the load factor of the linked hash set
     * @throws     IllegalArgumentException  if the initial capacity is less
     *               than zero, or if the load factor is nonpositive
     */
    public LinkedHashSet(int initialCapacity, float loadFactor) {
        super(initialCapacity, loadFactor, true);
    }

    /**
     * Constructs a new, empty linked hash set with the specified initial
     * capacity and the default load factor (0.75).
     *
     * @param   initialCapacity   the initial capacity of the LinkedHashSet
     * @throws  IllegalArgumentException if the initial capacity is less
     *              than zero
     */
    public LinkedHashSet(int initialCapacity) {
        super(initialCapacity, .75f, true);
    }

    /**
     * Constructs a new, empty linked hash set with the default initial
     * capacity (16) and load factor (0.75).
     */
    public LinkedHashSet() {
        super(16, .75f, true);
    }

    /**
     * Constructs a new linked hash set with the same elements as the
     * specified collection.  The linked hash set is created with an initial
     * capacity sufficient to hold the elements in the specified collection
     * and the default load factor (0.75).
     *
     * @param c  the collection whose elements are to be placed into
     *           this set
     * @throws NullPointerException if the specified collection is null
     */
    public LinkedHashSet(Collection<? extends E> c) {
        super(Math.max(2*c.size(), 11), .75f, true);
        addAll(c);
    }
}

 List中同理 EmptySet 是实现一个空的Set, 然后 SynchronizedSet 实现一个同步级的 Set,UnmodifiableSet针对修改的方法实现抛出异常来实现了不允许修改的含义。

AbstractSet的子类提供的方法几乎没有对Collection接口进行特别的添加,同时java提供了另外一种Set接口: public interface SortedSet<E> extends Set<E>,我们可以看出这种接口继承至Set同时根据类名的意思就是可排序的Set接口,同时它新提供了以下接口方法:

Method Summary


 Comparator<? super E>

comparator() 

          Returns the comparator used to order the elements in this set, or null if this set uses the natural orderingof its elements.

 E

first() 

          Returns the first (lowest) element currently in this set.

 SortedSet<E>

headSet(E 

          Returns a view of the portion of this set whose elements are strictly less than toElement.

 E

last() 

          Returns the last (highest) element currently in this set.

 SortedSet<E>

subSet(E fromElement, E 

          Returns a view of the portion of this set whose elements range from fromElement, inclusive, to toElement, exclusive.

 SortedSet<E>

tailSet(E 

          Returns a view of the portion of this set whose elements are greater than or equal to fromElement.

SortedSet,java1.6又对SortedSet接口进行了扩展出了NavigableSet接口,TreeSet增加了NavigableSet接口的实现,其中NavigableSet接口多出了以下方法:

Method Summary


 E

ceiling(E 

          Returns the least element in this set greater than or equal to the given element, or null if there is no such element.

 Iterator<E>

descendingIterator() 

          Returns an iterator over the elements in this set, in descending order.

 NavigableSet<E>

descendingSet() 

          Returns a reverse order view of the elements contained in this set.

 E

floor(E 

          Returns the greatest element in this set less than or equal to the given element, or null if there is no such element.

 NavigableSet<E>

headSet(E 

          Returns a view of the portion of this set whose elements are less than (or equal to, if inclusive is true)toElement.

 E

higher(E 

          Returns the least element in this set strictly greater than the given element, or null if there is no such element.

 E

lower(E 

          Returns the greatest element in this set strictly less than the given element, or null if there is no such element.

 E

pollFirst() 

          Retrieves and removes the first (lowest) element, or returns null if this set is empty.

 E

pollLast() 

          Retrieves and removes the last (highest) element, or returns null if this set is empty.

 NavigableSet<E>

subSet(E fromElement, boolean fromInclusive, E 

          Returns a view of the portion of this set whose elements range from fromElement to toElement.

 SortedSet<E>

subSet(E fromElement, E 

          Returns a view of the portion of this set whose elements range from fromElement, inclusive, to toElement, exclusive.

 NavigableSet<E>

tailSet(E 

          Returns a view of the portion of this set whose elements are greater than (or equal to, if inclusive is true) fromElement.

        接口中多出了更多的和顺序性相关的接口,包括倒序(descending*),临界的(ceiling,floor,higher,lower)最大值,最小值,另外提供了pollFirst, pollLast方法进行取出并删除首尾,同时对headSet,tailSet进行增强,这两个新方法提供了是否包含equals本元素。

CopyOnWriteArraySet内部的数据结构,所有的方法都是通过调用 al 来实现的。具有Set特性的方法,通过CopyOnWriteArrayList提供的 addAllAbsent, addIfAbsent, remove等方法来实现其功能。可以看到CopyOnWriteArraySet 只是使用了 CopyOnWriteArrayList里的几个特有方法实现了Set的功能,其基本的内部原理都还和CopyOnWriteArrayList一样。

ConcurrentNavigableMap相应的方法实现。

CopyOnWriteArraySet 使用了之前分析过的 CopyOnWriteArrayList做为内部数据结构进行实现的。分析Set的并发情况,其基本并发情况跟在说List中的情况基本一致,HashSet , LinkedHashSet, TreeSet 线程非安全,不适合多线程下被多个线程使用,多线程下的Set考虑使用 Collections.SynchronizedSet ,CopyOnWriteArraySet ,其中CopyOnWriteArraySet 读操作频繁,写操作较少的情况下性能较高。Collections.UnmodifiableSet 用于在确定不让此数据结构不能修改的情况下使用,基本理论和List并发情况的论述中是一致的。