Factory methods for SequencedSet and SequencedMap

David Alayachew davidalayachew at gmail.com
Sat Jan 18 01:00:54 UTC 2025


Thanks for the corrections folks. I was thinking from the perspective of
LSP. I now see that there is the performance perspective to consider too.

Now that said, I don't understand your comment Joe Darcy. Could you explain
it in more detail?

My initial pick up of your comment is that, the parameter types and the
return types of a method must match the types exactly between releases,
otherwise there are no bridge methods FOR STATIC TYPES. But as for why, I
don't understand.

I know that static methods are not so much inherited as they are just given
as is (hence why there is not really a static abstract method). But I don't
quite see the line connecting that with no bridge methods for static. Maybe
I don't understand bridge methods well enough.

On Fri, Jan 17, 2025, 12:32 PM Joseph D. Darcy <joe.darcy at oracle.com> wrote:

> On 1/16/2025 11:26 PM, Rafael Winterhalter wrote:
>
>
> Would it even be possible to change the return types of Set.of(...) and
> Map.of(...) without breaking binary compatibility?
>
>
> In short, no.
>
> The methods in question are *static* methods. Switching to covariant
> overrides with more precise return types works for subclasses because of
> bridge methods.
>
> In a bit more detail, in a covariant override a single method in the
> source code gets translated into multiply methods in the class file.
> References to methods in the class file use the argument types and return
> type so if an old class file refers to the previously declared source-level
> return type, there is the bridge method present to be linked to (for binary
> compatibility) and then executed.
>
> -Joe
>
>
>
> I also think that the randomization of Set.of(...) and Map.of(...) is a
> good property as it uncovers bugs early if one relies on iteration order.
> This especially since those methods are often used in tests where
> production code would use a proper HashSet which cannot guarantee iteration
> order for good reasons. Exactly here I think the new interfaces are a good
> addition as it uncovers such misconceptions. If code relies on insertion
> order, providing a Set.of(...) does no longer compile, what is a good thing.
>
> To me, adding SequencedSet.of(...) and SequencedMap.of(...) sounds like
> the right approach, with implementations similar to that of Set.of(...) and
> Map.of(...). As for megamorphism, I think the chance of encounter at a call
> site is similar, as Set12 and SetN from the Set interface are typically
> combined with HashMap. As for a possible SequencedSet12 and SequencedSetN,
> I think they would normally be seen with LinkedHashSet.
>
> Best regards, Rafael
>
> Am Fr., 17. Jan. 2025 um 00:36 Uhr schrieb David Alayachew <
> davidalayachew at gmail.com>:
>
>> I should also add, the documentation went out of their way to specify
>> that iteration order is unspecified.
>>
>> Also, I see Rémi's comment, but that's even more unconvincing to me.
>>
>> Map.of has an upper limit of 10 entries, and Map.ofEntries has an upper
>> limit of that Java max file size limit thing. You all know what I am
>> talking about.
>>
>> Point is, both of these static factories were meant to be used on a small
>> number of entries. If it truly has just been not done until now, then the
>> bug database will confirm that easily.
>>
>> When I get back, I can check myself.
>>
>> On Thu, Jan 16, 2025, 6:25 PM David Alayachew <davidalayachew at gmail.com>
>> wrote:
>>
>>> I guess let me ask the obvious question.
>>>
>>> Chesterton's fence -- why wasn't this done before? I refuse to believe
>>> that this idea wasn't thought up years ago, which leads me to believe there
>>> was a reason that it hasn't been done.
>>>
>>> Is there any way we can look this up in the bug database or something?
>>>
>>> On Thu, Jan 16, 2025, 2:28 PM Jens Lideström <jens at lidestrom.se> wrote:
>>>
>>>> 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
>>>>
>>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/core-libs-dev/attachments/20250117/b4a0a3ca/attachment-0001.htm>


More information about the core-libs-dev mailing list