他们之间有什么区别?我知道
LinkedHashSet是HashSet的有序版本 在所有元素中维护一个双向链表。使用此类而不是HashSet 当你关心迭代顺序时。当你遍历一个HashSet时 order是不可预测的,而LinkedHashSet允许你遍历元素 按插入顺序排列。
但是在LinkedHashSet的源代码中,只有HashSet的调用构造函数。那么双链接列表和插入顺序在哪里?
答案 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
,因为它整体效果更好):
HashMap
,因为大部分时间我们都使用Set结构进行迭代。效果测试:
------------- 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
无法预测。下次再订购。
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的:
LinkedHashSet:
答案 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简单的组合:)