Ordering of Elements in Java Hashset

Ordering of elements in Java HashSet

The second one (just using HashSet) is only a coincidence. From the JavaDocs:

This class implements the Set interface, backed by a hash table (actually a HashMap instance). It makes no guarantees as to the iteration order of the set; in particular, it does not guarantee that the order will remain constant over time. This class permits the null element.

The third one (LinkedHashSet) is designed to be like that:

Hash table and linked list implementation of the Set interface, with predictable iteration order. This implementation differs from HashSet in that it maintains a doubly-linked list running through all of its entries. 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.)

Understanding order of elements in stream generated from HashSet

There is a little bit of mis-understating here indeed. A HashSet or any Set is not about order, unless TreeSet that is ordered based on a Comparator.

At the moment, under java-8 once you put elements into a HashSet (and don't change it) - there will be an order of how the elements are laid out; but again, under the condition that you do not add or remove any of them. This can change at any point in time, so don't rely on it.

For example running this:

 String[] colors = new String[] { "red", "green", "blue", "orange" };
List<String> colorsList = Arrays.asList(colors);

HashSet<String> colorsSet = new HashSet<>();
colorsSet.addAll(colorsList);
System.out.println(colorsSet);

No matter how many times under java-8 at the moment you will always get the same output:

[red, orange, green, blue]

But once you do some internal re-shuffling:

    for (int i = 0; i < 1000; ++i) {
colorsSet.add("" + i);
}

for (int i = 0; i < 1000; ++i) {
colorsSet.remove("" + i);
}

System.out.println(colorsSet); // [blue, red, green, orange]

You can see that the output changes, because Sets don't have an order.
The key point to take is that there is no order, the fact that you do see an order is not a guarantee to happen every time - there might be a build in java-8 that will break this order. And in fact that is easily observable with java-9 for example - where there is a randomization pattern for new Sets.

If you run this multiple times, the result will differ:

 Set<String> set = Set.of("red", "green", "blue", "orange");
System.out.println(set);

So obviously of you stream from such a Set the order will not be guaranteed and thus you will indeed see different results from run to run.

Hashset ordering issue

Coincidence. It just happens that the hashCode of Character is it’s numeric value. If you keep adding more characters than there are hash buckets in the HashSet, you’ll see that they get out of order.

Order of element in hashSet

The order of the entries in a HashMap or HashSet is predictable in theory for current generation and older implementations.

However, the prediction depends on at least:

  • the hash values of the keys,
  • the initial capacity of the set or map,
  • the precise sequence in which the keys were added to and removed from the set / map,
  • the specific implementation of HashSet or HashMap used (the behaviour is Java version dependent, and possibly depended on patch level), and
  • for Java 8 and later, whether or not the keys are Comparable.

If you have all of that information (and you are prepared to emulate the insertion / removal sequence), you can accurately predict the iteration order. However, it would be tricky to implement, and expensive to run ...


In your example, the hash values are the same, the initial HashSet capacity is the same, the insertion order is the same, and the HashSet implementation is the same. In those circumstances (and given the precise algorithms used) the iteration order is going to repeatable ... even if though it would difficult to predict.

In this case, the order is not "random" because there is no randomness in the process that builds the HashSet. Just calculations that are complicated and opaque ... but deterministic.


I have read in java 1.7 docs that "It makes no guarantees as to the iteration order of the set". what is meaning of this?

What is means is that the javadoc is not committing to any specific behaviour vis-a-vis the ordering. Certainly, there is no commitment to portable behaviour.


See also: Order of values retrieved from a HashMap

Why HashSet order always same for my program?

The reason for this behaviour is that a HashSet is backed by a HashMap, which in turn is backed by an array of Entry-objects. where the hash is used to find the index of the array. So there is always an order of elements in a HashSet (the order of the array), you just don't have any guarantees as to what this order is.

As far as I can tell from the code, the order of the HashSet is determined (or at least affected) by the order of the computed hashes of its elements. Then, with relatively simple inputs (like your single character string), one might assume that there is a strict ordering of the hashes, which will give you what seems to be a natural ordering. With more complex objects, and thus more complex hash computations, the hashes will be more spread, and the ordering "more random".

Also, like it's been pointed out, "no guarantee of ordering" does not imply "guaranteed random ordering".

The hashcode-method of the String class also comes into play here, for single character Strings the hashcode will just be the int value of the one char in the String. And since char's int values are ordered alphabetically, so will the computed hashes of single char Strings.

Java HashSet - is there a way to specify the order in which elements will be displayed?

You can Use LinkedHashSet it keeps order of elements.

Hash table and linked list implementation of the Set interface, with predictable iteration order. This implementation differs from HashSet in that it maintains a doubly-linked list running through all of its entries. 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.)

LinkedHashSet

Java Set retain order?

The Set interface does not provide any ordering guarantees.

Its sub-interface SortedSet represents a set that is sorted according to some criterion. In Java 6, there are two standard containers that implement SortedSet. They are TreeSet and ConcurrentSkipListSet.

In addition to the SortedSet interface, there is also the LinkedHashSet class. It remembers the order in which the elements were inserted into the set, and returns its elements in that order.

Iteration order of HashSet

Absolutely not.

The insertion order directly influences the iteration order whenever you have a bucket collision:

When two elements end up in the same bucket, the first one that was inserted will also be the first one returned during iteration, at least if the implementation of collision handling and iteration is straightforward (and the one in Sun's java.util.HashMap is)



Related Topics



Leave a reply



Submit