2017-10-19 127 views
4

构造函数LinkedHashSet(Collection<? extends E> c)是否保证其参数的保存顺序,假设参数是一个有序集合?我们如何确定这一点?LinkedHashSet构造函数是否保存顺序

的Javadoc文档只字未提顺序:

构造一个新的链接哈希具有相同元素的 指定集合设置。链接的哈希集创建时的容量足以容纳指定集合 中的元素和默认加载因子(0.75)。

我没有看到任何理由不维护秩序,但我想知道它是否有保证(目前和未来的实施)。

+1

[JDoc](https://docs.oracle.com/javase/7/docs/api/java/util/LinkedHashSet.html) - >'这个链表定义了迭代顺序,它是顺序元素被插入集合(插入顺序)。请注意,如果元素重新插入到集合中,则插入顺序不受影响。 (如果s.contains(e)在调用之前立即返回true,则调用s.add(e)时,将元素e重新插入到集合s中。)'基本上它维护插入顺序。这允许您按照插入元素的顺序遍历集合。 – Sedrick

+1

@SedrickJefferson好的。该文件的这一部分表明,订单将被保留。 – AnnTea

回答

1

纵观Java的8实现java.util.LinkedHashSet的你有这样的构造:

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

那么什么是addAll的内容?

public boolean addAll(Collection<? extends E> c) { 
    boolean modified = false; 
    for (E e : c) 
     if (add(e)) 
      modified = true; 
    return modified; 
} 

addAll使用一个循环,通过构造函数中使用的集合:

for (E e : c) 

这意味着,如果在构造函数中使用收取执行是有序的(如java.util.TreeSet),那么新的内容LinkedHashSet实例也将被订购。

Java 9中的实现非常相似。

是的,在订购传入收集的情况下订单被保留。

您只能通过检查此特定情况下的实现来确定这一点。

+0

接受因为“您只能通过检查此特定情况下的实施来确定这一点。” – AnnTea

2

它保留通过集合的迭代器返回的顺序,因为它interntally使用addAll

遍历指定的集合,并添加迭代器返回到这个集合中的每个对象,反过来。

+0

您是否暗示实现无法更改?什么保证? – AnnTea

+3

@AnnTea技术上没有保证。然而,考虑到没有什么需要改进的地方,它们会改变实现,而且Java向后兼容的数量是不可思议的。尽管如此,创建自己的JDK并以不同的方式实现它并不符合规范。 – Kayaman

+0

@Kayaman这可能是我正在寻找的答案(尽管不希望)。 – AnnTea

相关问题