LinkedHashSet源码分析

LinkedHashSet源码分析

继承结构

public class LinkedHashSet<E>
    extends HashSet<E>
    implements Set<E>, Cloneable, java.io.Serializable {
    
    private static final long serialVersionUID = -2851667679971038690L;
}

通过源代码可以看到LinkedHashSet继承了HashSet类,实现了Set、Cloneable以及Serializable接口,通过实现了Set接口我们知道不允许包含相同的元素。可是这个功能限制是如何实现的,我们来看下源代码就可以一目了然了。

构造方法

/**
* 来自LinkedHashSet继承的HashSet的其中一个构造方法
*/
HashSet(int initialCapacity, float loadFactor, boolean dummy) {
  map = new LinkedHashMap<E,Object>(initialCapacity, loadFactor);
}

/**
* 来自LinkedHashSet继承的HashSet的其中一个属性
*/
private transient HashMap<E,Object> map;


/**
* 制定了初始容量和加载因子的Set
*/
public LinkedHashSet(int initialCapacity, float loadFactor) {
    super(initialCapacity, loadFactor, true);
}
 

/**
* 制定了初始容量的Set,使用系统默认的加载因子0.75
*/ 
public LinkedHashSet(int initialCapacity) {
    super(initialCapacity, .75f, true);
}
 
/**
* 直接调用了一个空的构造函数,默认初始化一个容量为16,加载因子为0.75的Set,
*/ 
public LinkedHashSet() {
    super(16, .75f, true);
}
 

/**
* 使用一个集合初始化Set.
*/  
public LinkedHashSet(Collection<? extends E> c) {
    super(Math.max(2*c.size(), 11), .75f, true);
    addAll(c);
}

原来这两个方法就是我们构造函数出现的。通过第一个方法HashSet,中有一个Map,那这又是什么呢。原来HashSet中有一个熟悉private transient HashMap map;这下我们明白了原来Set的底层是采用一个Map实现的。这个很重要的东西,通过Map的相关方法调用来模仿Set的功能。Super方法做的事情就是创建了一个指定大小和加载因子的Map,addAll()方法就是遍历这个集合然后依次将他们放入我们的Map中去,从而实现了用一个集合直接构造含有值的Set。

回过头来我们看看上面的四个构造方法。第一个方法就是制定了初始容量和加载因子的Set,第二个构造函数就是制定了初始容量的Set,使用系统默认的加载因子0.75。第三个构造函数就是直接调用了一个空的构造函数,默认初始化一个容量为16,加载因子为0.75的Set,最后一个就是使用一个集合初始化Set.

一些方法

add(E e)

public boolean add(E e) {
   return map.put(e, PRESENT)==null;
}

remove()和clear()

public boolean remove(Object o) {
   return map.remove(o)==PRESENT;
}
 
 
public void clear() {
    map.clear();
}

LinkedHashSet集合是根据元素的hashCode值来决定元素的存储位置,但是它同时使用链表维护元素的次序。这样使得元素看起 来像是以插入顺序保存的,也就是说,当遍历该集合时候,LinkedHashSet将会以元素的添加顺序访问集合的元素。LinkedHashSet在迭代访问Set中的全部元素时,性能比HashSet好,但是插入时性能稍微逊色于HashSet。Set的很多操作都是依赖Map来实现的,下次来学习下Map的源码相关。

通过之前的学习,我们知道TreeSet和LinkedHashSet都是有序的,那它们有何不同?

LinkedHashSet并没有实现SortedSet接口,它的有序性主要依赖于LinkedHashMap的有序性,所以它的有序性是指按照插入顺序保证的有序性;

而TreeSet实现了SortedSet接口,它的有序性主要依赖于NavigableMap的有序性,而NavigableMap又继承自SortedMap,这个接口的有序性是指按照key的自然排序保证的有序性,而key的自然排序又有两种实现方式,一种是key实现Comparable接口,一种是构造方法传入Comparator比较器。

你可能感兴趣的:(Java基础,初识java)