HashSet与LinkedHashSet

时间:2011-02-22 16:04:34

标签: java hashset linkedhashset

他们之间有什么区别?我知道

  

LinkedHashSet是HashSet的有序版本   在所有元素中维护一个双向链表。使用此类而不是HashSet   当你关心迭代顺序时。当你遍历一个HashSet时   order是不可预测的,而LinkedHashSet允许你遍历元素   按插入顺序排列。

但是在LinkedHashSet的源代码中,只有HashSet的调用构造函数。那么双链接列表和插入顺序在哪里?

10 个答案:

答案 0 :(得分:62)

答案在于构造函数 LinkedHashSet用于构造基类:

public LinkedHashSet(int initialCapacity, float loadFactor) {
    super(initialCapacity, loadFactor, true);      // <-- boolean dummy argument
}

...

public LinkedHashSet(int initialCapacity) {
    super(initialCapacity, .75f, true);            // <-- boolean dummy argument
}

...

public LinkedHashSet() {
    super(16, .75f, true);                         // <-- boolean dummy argument
}

...

public LinkedHashSet(Collection<? extends E> c) {
    super(Math.max(2*c.size(), 11), .75f, true);   // <-- boolean dummy argument
    addAll(c);
}

描述了一个带有布尔参数的HashSet构造函数的一个例子,如下所示:

/**
 * 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);
}

答案 1 :(得分:24)

LinkedHashSet的构造函数调用以下基类构造函数:

HashSet(int initialCapacity, float loadFactor, boolean dummy) {
  map = new LinkedHashMap<E, Object>(initialCapacity, loadFactor);
}

如您所见,内部地图是LinkedHashMap。如果你查看LinkedHashMap,你会发现以下字段:

private transient Entry<K, V> header;

这是有问题的链接列表。

答案 2 :(得分:9)

你应该查看它调用的HashSet构造函数的来源......它是一个特殊的构造函数,使得Map支持LinkedHashMap而不仅仅是HashMap

答案 3 :(得分:9)

HashSet是无序和未排序的Set。 LinkedHashSet是HashSet的有序版本.HashSet和LinkedHashSet之间的唯一区别是LinkedHashSet维护插入顺序。当我们遍历HashSet时,顺序是不可预测的,而在LinkedHashSet的情况下它是可预测的。 LinkedHashSet维护插入顺序的原因是因为底层数据结构是双向链接列表。

答案 4 :(得分:5)

我建议您在大多数情况下使用 LinkedHashSet ,因为它整体效果更好):

  1. 可预测 迭代订单LinkedHashSet (Oracle)
  2. LinkedHashSet对于插入而言比HashSet更昂贵;
  3. 一般来说,性能略好于 HashMap ,因为大部分时间我们都使用Set结构进行迭代。
  4.   

    效果测试:

    ------------- TreeSet -------------
     size       add  contains   iterate
       10       746       173        89
      100       501       264        68
     1000       714       410        69
    10000      1975       552        69
    ------------- HashSet -------------
     size       add  contains   iterate
       10       308        91        94
      100       178        75        73
     1000       216       110        72
    10000       711       215       100
    ---------- LinkedHashSet ----------
     size       add  contains   iterate
       10       350        65        83
      100       270        74        55
     1000       303       111        54
    10000      1615       256        58
    

    您可以在此处查看源测试页:The Final Performance Testing Example

答案 5 :(得分:3)

HashSet的: 实际上是无序的。 如果您传递参数意味着

Set<Integer> set=new HashSet<Integer>();
for(int i=0;i<set.length;i++)
{
  SOP(set)`enter code here`
}

输出: 可能2,1,3无法预测。下次再订购。

产生FIFO订单的

LinkedHashSet()

答案 6 :(得分:2)

<强> HashSet的:

带下划线的数据结构是Hashtable。 不允许重复的对象。不保留插入顺序,它基于对象的哈希码。 空插入是可能的(只有一次)。 它实现了Serializable,Clonable但不是RandomAccess接口。 如果频繁操作是搜索操作,HashSet最好选择。

  

在HashSet中不允许重复。如果用户在我们未获得任何编译或运行时异常时尝试插入重复项。 add方法只返回false。

<强>构造

  

HashSet h = new HashSet();创建一个空的HashSet对象,默认初始容量为16,默认填充率(加载因子)为0.75。

     

HashSet h = new HashSet(int initialCapacity);创建一个具有指定initialCapacity的空HashSet对象,默认填充率为0.75。

     

HashSet h = new HashSet(int initialCapacity,float fillRatio);

     

HashSet h = new HashSet(Collection c);为给定集合创建等效的HashSet对象。此构造函数用于集合对象之间的相互转换。

<强> LinkedHashSet:

它是HashSet的子类。除了以下差异外,它与HashSet完全相同,包括(构造函数和方法)。

的差异 HashSet的:

  1. 带下划线的数据结构是Hashtable。
  2. 不保留广告订单。
  3. 介绍了1.2版本。
  4. LinkedHashSet:

    1. 带下划线的数据结构是LinkedList和Hashtable的组合。
    2. 保留广告订单。
    3. 1.4版本的产品。

答案 7 :(得分:2)

HashSet 不保持插入项目的顺序
LinkedHashSet 维护插入项目的顺序

实施例

Set<String> set = ...;// using new HashSet<>() OR new LinkedHashSet<>()
set.add("2");
set.add("1");
set.add("ab");
for(String value : set){
   System.out.println(value);
}  

HashSet输出

1
ab
2

LinkedHashSet输出

2
1
ab

答案 8 :(得分:1)

如果您查看从LinkedHashSet类调用的构造函数,您将看到内部的LinkedHashMap用于支持目的。

答案 9 :(得分:0)

所有方法和构造函数都相同,但只有一个区别是LinkedHashset将维护插入顺序,但不允许重复。

Hashset不会维护任何广告订单。 它是List和Set简单的组合:)