4

Does the constructor LinkedHashSet(Collection<? extends E> c) guarantee preserved order of its argument, assuming the argument is an ordered collection? How can we be sure of that?

The Javadoc documentation says nothing about order:

Constructs a new linked hash set with the same elements as the specified collection. The linked hash set is created with an initial capacity sufficient to hold the elements in the specified collection and the default load factor (0.75).

I don't see any reason for it to not preserve order but I want to know if it is guaranteed (for current and future implementations).

AnnTea
  • 502
  • 7
  • 15
  • 1
    [JDoc](https://docs.oracle.com/javase/7/docs/api/java/util/LinkedHashSet.html) -> `This linked list defines the iteration ordering, which is the order in which elements were inserted into the set (insertion-order). Note that insertion order is not affected if an element is re-inserted into the set. (An element e is reinserted into a set s if s.add(e) is invoked when s.contains(e) would return true immediately prior to the invocation.)` Basically, it maintains the insertion order. This allows you to iterate through the set in the same order as the elements were inserted. – Sedrick Oct 19 '17 at 13:34
  • 1
    @SedrickJefferson Good catch. That part of the documentation suggests that the order will be preserved. – AnnTea Oct 19 '17 at 15:58

2 Answers2

3

It preserves the order returned by the iterator of the collection as it interntally uses addAll:

iterates over the specified collection, and adds each object returned by the iterator to this collection, in turn.

Jean Logeart
  • 48,718
  • 10
  • 76
  • 108
  • Are you implying that the implementation can not change? What guarantees that? – AnnTea Oct 19 '17 at 13:25
  • 3
    @AnnTea technically there is no guarantee. However it would be incredible unlikely that they would *change* the implementation, considering there's nothing to improve, and the amount of backwards compatibility Java has. Still, it wouldn't be against the spec to create your own JDK and implement it differently. – Kayaman Oct 19 '17 at 13:49
  • @Kayaman This is possibly the answer I am looking for (all though not hoping for). – AnnTea Oct 19 '17 at 15:49
3

Looking at the Java 8 implementation of java.util.LinkedHashSet you have this constructor:

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

So what is the content of addAll?

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

addAll uses a loop through the collection used in the constructor:

for (E e : c)

This means that if the collection implementation used in the constructor is ordered (e.g. java.util.TreeSet), then the content of the new LinkedHashSet instance will also be ordered.

The implementation in Java 9 is very much the same.

Yes, the order is preserved in case the incoming collection is ordered.

You can only be sure about this by checking the implementation in this specific case.

gil.fernandes
  • 9,585
  • 3
  • 41
  • 57
  • Accepted because of "You can only be sure about this by checking the implementation in this specific case." – AnnTea Oct 19 '17 at 15:51