Factory methods for SequencedSet and SequencedMap

Jens Lideström jens at lidestrom.se
Thu Jan 16 19:27:03 UTC 2025


Having the result Map.of and Set.of preserve the insertion order would 
often be convenient.

More often than not programs iterate over the contents of a maps and 
sets at some point. For example to present the values in a GUI, for 
serialisation, or even for error printouts. In all those cases having a 
fixed iteration order is much better than having a random iteration 
order.

Often it is even a subtle bug to have a random iteration order. For 
example, I ran in to a situation where jdeps printed a error message 
containing a list of modules. But the list was in a different order on 
each run of the program! It took me a while to figure out that it was 
actually the same list. A possible explanation is that jdeps is 
implemented using Map.of or Set.of.

Because of this I think I would be better if the most commonly used 
standard collection factories produced collections with a fixed 
iteration order.

Guavas ImmutableMap and ImmutableSet also preserve insertion order.

Regards,
Jens Lideström


On 2025-01-16 08:44, Remi Forax wrote:

> -------------------------
> 
>> From: "Rafael Winterhalter" <rafael.wth at gmail.com>
>> To: "core-libs-dev" <core-libs-dev at openjdk.java.net>
>> Sent: Thursday, January 16, 2025 8:13:17 AM
>> Subject: Factory methods for SequencedSet and SequencedMap
> 
>> Hello,
> 
> Hello,
> 
>> I am happily taking SequencedSet and SequencedMap into use, but one 
>> inconvenience I encounter is the lack of factory methods for the two.
>> In code where many (initial) collections have zero or one element (for 
>> later aggregation), I now write Set.of()/Set.of(one) and 
>> Map.of()/Map.of(key, value), as it makes the code shorter and more 
>> readable. Those collections are of course implicitly sequenced, but 
>> now I must make the variable type of the surrounding monad Set and 
>> Map, and simply assume that a LinkedHashSet or LinkedHashMap is used 
>> when a collection of more than one element is set, without requiring 
>> the interface type. This does not require any type casting, as I rely 
>> on the iteration order only, but the code loses some of its 
>> expressiveness.
>> I did not find any discussion around introducing factories for 
>> SequencedSet.of(...) and SequencedMap.of(...), similar to those that 
>> exist in the Set and Map interfaces. Was this ever considered, and if 
>> not, could it be?
> 
> Thanks for re-starting that discussion, it was talked a bit, but not as 
> it should be.
> 
> So the issue is that currently we do not have any compact, unmodifiable 
> and ordered Set/Map implementation,
> one use case is when you have data that comes from a JSON object as a 
> Map and you want to keep the inserted order, if by example the JSON is 
> a config file editable by a human, an other example is in unit tests 
> where you want to help the dev to read the output of the test so the 
> code that creates a Set/Map and what is outputed by the test should be 
> in the same order.
> Currently there is no good solution for those use cases because 
> Set|Map.copyOf() does not keep the ordering.
> 
> I see two solutions, either we add a new 
> SequenceSet|SequenceMap.of/copyOf, or we change the impleemntation of 
> Set|Map.of()/copyOf().
> Python had gone for the latter solution, which has the advantage a 
> being simple from the user POV, but from an algorithm expert POV, a Set 
> and a SequencedSet are different concepts we may want to emphasis ?
> 
>> Best regards, Rafael
> 
> regards,
> Rémi


More information about the core-libs-dev mailing list