0

During preparation for Java exam, I encountered this problem:

public static Function<String, String> change = i -> {
        if (i.equals("Au"))
            return "Ne";
        else
            return i;
    };

Set<String> someStrings = Set.of("Au", "Ja", "Ta", "Cy", "Cu");
        someStrings = someStrings
                .stream()
                .map(change)
                .map(n -> n.substring(0, 1))
                .collect(Collectors.toSet());
        for (String s : someStrings) {
            System.out.print(s);
        }

Answers to this question suggest that order of printing is important. But how one should determine order of printing in this case? My only guess it is reversed order of listing elements in Set.of() method.

  • 2
    a `HashSet` has no deterministic ordering of its elements – Lino Apr 22 '21 at 11:39
  • 2
    @Lino: that is true, but not that not a single `HashSet` is (overtly) involved in this code. But the same statement is still true about the `Set` interface itselt: `Set` provides no defined ordering. – Joachim Sauer Apr 22 '21 at 11:40
  • The documentation for [`Collectors.toSet()`](https://docs.oracle.com/javase/8/docs/api/java/util/stream/Collectors.html#toSet--) says *There are no guarantees on the type, mutability, serializability, or thread-safety of the Set returned*. Only a [`TreeSet`](https://docs.oracle.com/javase/8/docs/api/java/util/TreeSet.html) can have a defined ordering of its elements. Since we don't know if it's a TreeSet, there's no guarantee the elements are ordered. – Stefan Zhelyazkov Apr 22 '21 at 11:43
  • @JoachimSauer IIRC the implementation of `Collectors.toSet()` uses a `HashSet`, but I still agree with your points – Lino Apr 22 '21 at 11:44
  • @Lino: **one** implementation might (or even most/all), but it's explicitly specified that it makes no guarantee about the type of the returned set. – Joachim Sauer Apr 22 '21 at 11:46
  • As everyone pointed already HashSet does not guarantee any insertion order but we can use TreeSet which does , in context of streams this can be achieved in this way `.collect(Collectors.toCollection(TreeSet::new));` – Misa D. Apr 22 '21 at 11:56
  • 1
    @MisaD.: `TreeSet` isn't ordered, it's sorted: it doesn't maintain insertion order, it maintains "natural order". `LinkedHashSet` maintains insertion order. – Joachim Sauer Apr 22 '21 at 12:09
  • @JoachimSauer indeed you are right then he should use LinkedHashSet ty for pointing to my mistake. – Misa D. Apr 22 '21 at 12:12
  • 1
    Seems to be the same exam, as in [this question](https://stackoverflow.com/q/67160632/2711488), we had only three days ago. Perhaps, there are even more questions caused by this horrible exam. – Holger Apr 22 '21 at 17:30

1 Answers1

1

Set in general provides no defined order for its iterators:

The elements are returned in no particular order [...].

Set.of is explicitly specified to return an unordered Set:

  • The iteration order of set elements is unspecified and is subject to change.

Collectors.toSet is defined to construct an unspecified Set, which means the general rules of Set apply (see above).

There is nothing in the documentation that defines any kind of reliable order in here. Any order that an implementation ends up returning here is valid.

Joachim Sauer
  • 302,674
  • 57
  • 556
  • 614