常用的两种set:TreeSet,HashSet
实现:都是基于相应的map接口来的,如TreeSet底层用的TreeMap,HashSet底层用的HashMap。映射到map,key为set中你要放置的量,value为一个全局的object对象(节约空间)
TreeSet
看一下源码结构
public class TreeSet extends AbstractSet
implements NavigableSet, Cloneable, java.io.Serializable
{
/** * The backing map. */
private transient NavigableMap m;
// Dummy value to associate with an Object in the backing Map
private static final Object PRESENT = new Object();
/** * Constructs a set backed by the specified navigable map. */
TreeSet(NavigableMap m) {
this.m = m;
}
/** * Constructs a new, empty tree set, sorted according to the * natural ordering of its elements. All elements inserted into * the set must implement the {@link Comparable} interface. * Furthermore, all such elements must be mutually * comparable: {@code e1.compareTo(e2)} must not throw a * {@code ClassCastException} for any elements {@code e1} and * {@code e2} in the set. If the user attempts to add an element * to the set that violates this constraint (for example, the user * attempts to add a string element to a set whose elements are * integers), the {@code add} call will throw a * {@code ClassCastException}. */
public TreeSet() {
this(new TreeMap());
}
public TreeSet(Comparator super E> comparator) {
this(new TreeMap<>(comparator));
}
特性:
基于树的实现,能保证元素的排列顺序,且插入、查找、删除的时间为log(n)
HashSet
结构和TreeSet大同小异
特性:
基于hash表实现,不保持元素的顺序,(This class implements the Set interface, backed by a hash table (actually a HashMap instance). 提供常量时间的性能,对于add, remove, contains and size(如果hash函数将元素散开在不同的桶上的话) Iterating over this set requires time proportional to the sum of the HashSet instance’s size (the number of elements) plus the “capacity” of the backing HashMap instance (the number of buckets). Thus, it’s very important not to set the initial capacity too high (or the load factor too low) if iteration performance is important. 在HashSet上的迭代的时间和 hashset实例的大小+容器的capacity大小之和 成正比