2

I have array of Strings which actually in nothing but list of integers coming from file. I converted it to HashSet so as to remove duplicates as follows:

Set<String> intSet = new HashSet<String>(Arrays.asList(strArr));

I expected that it all the numbers to be in order but off course, since this is a string and not integer list, it may not come in order. But whenever I try to print this HashSet, I always get output as follows:

[3, 2, 1, 4]
[3, 2, 5, 4]

Every time, if 3 is present it is considered to be first element. I am not getting why it is acting this way? Can anyone please explain me this.

Rahul Shelke
  • 2,052
  • 4
  • 28
  • 50

4 Answers4

9

HashSet doesn't maintain a predictable order, it will depend on the hashCode of the object reference. If you want to maintain the order in which the elements are inserted, use a LinkedHashSet. If you want to maintain the elements always sorted, use a TreeSet.

Luiggi Mendoza
  • 85,076
  • 16
  • 154
  • 332
  • Thanks @Luiggi Mendoza. But why HashSet is taking 3 as first element always? I am not getting this... – Rahul Shelke May 24 '13 at 14:24
  • I would not agree that the order is unpredictable - it is hash-dependent. And for two equal Strings, their hash is the same too. So the order is predictable and constant for Strings. – Michael Schmeißer May 24 '13 at 14:26
  • 1
    @LuiggiMendoza The order is deterministic, so running it several times should not make a difference. – assylias May 24 '13 at 14:26
  • 1
    @assylias in case of `String`s, it will be. – Luiggi Mendoza May 24 '13 at 14:27
  • 1
    @Michael Schmeißer: No, the order is implementation specific and not predictable. Even if the HashSet implementation in Oracle's JVM returns a *consistent* order, you can not be sure that the same order is kept across different VM versions or VMs from different vendors. – jarnbjo May 24 '13 at 14:58
9

The order of return is dependent on an internal hashing algorithm, to which you are supposed to be indifferent. (The idea behind the hashing algorithm is to disperse key values uniformly across an internal table. You probably get 3 back every time since this algorithm is probably deterministic).

If you want things back in lexographic order then use a TreeSet.

To preserve the order of insertion, use a LinkedHashSet.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
2

This is due to the implementation of HashSet. If you would like a Set that sustains some order, you could use a LinkedHashSet instead.

From the LinkedHashSet javadoc:

This implementation spares its clients from the unspecified, generally chaotic ordering provided by HashSet, without incurring the increased cost associated with TreeSet. It can be used to produce a copy of a set that has the same order as the original, regardless of the original set's implementation:

Sheldon Warkentin
  • 1,706
  • 2
  • 14
  • 31
0

From Oracle documentation we can find the HashSet class implements the set interface and internally backed by Hash Table.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.

Hence, I will suggest You to use TreeSet if You care for the order of element.

public static void main(String[] args){
        String version = System.getProperty("java.version");
        System.out.println("JDK version-"+version); 
        SortedSet<String> ss = new TreeSet<String>();
        ss.add("1");
        ss.add("3");
        ss.add("2");
        ss.add("4");
        System.out.println(ss);

    }

o/p:

JDK version-1.6.0
[1, 2, 3, 4]