ReversibleCollection proposal
Stuart Marks
stuart.marks at oracle.com
Wed Apr 21 17:38:23 UTC 2021
On 4/19/21 4:05 PM, forax at univ-mlv.fr wrote:
>> * There's a useful clump of semantics here, combined with sensible operations
>> that
>> rely on those semantics. There are a lot of places in the spec where there is
>> hedging of the form "if the collection has an ordering, then... otherwise the
>> results are undefined". This is unnecessary in the context of a new type.
>> Furthermore, the new operations fit well with the new types' semantics, with no
>> hedging necessary.
>
> You can only say that a reversible collection has an ordering. But usually you want the opposite, all collections that have an ordering are a reversible collection. But while this can be true for the implementations inside the JDK that will never be true in Java because there all already collection implementations with an ordering which do not implement ReversibleCollection.
>
> Sadly, this ship has sailed.
> The spec will still have to say "if the collection has an ordering", otherwise the new semantics is not a backward compatible.
The value being provided here is that the ReversibleCollection interface provides a
context within which specs no longer need to hedge about "if the collection has an
ordering". APIs that produce or consume ReversibleCollection no longer need to
include this hedge, or have disclaimers about ordering. Potential new
ReversibleCollection implementations also need not worry about this issue in the
same way they did when they were forced to implement Collection directly.
Of course there will always be ordered collections that don't implement
ReversibleCollection. (Examples of this are the Queue-but-not-Deque implementations
in the JDK and 3rd party ordered collections that implement Collection directly.)
Existing APIs that produce or consume Collection but have stipulations about
ordering may need to remain, although some could be adjusted depending on the context.
You rightly point out that this problem can never be solved in general. However,
it's not a goal for ReversibleCollection to represent *all* ordered collections, so
it's hardly a criticism that it doesn't solve a problem that cannot be solved.
>> * These semantics appear across a broad range of existing collection types and
>> implementations. It's quite valuable to have a type that unifies the common
>> pieces
>> of List, Deque, SortedSet, and LinkedHashSet into a single abstraction.
>
> yes in term of documentation, but in Java, it also means that you can use that interface as a type.
>
> For a List, a Deque or a Set, there are known algorithms that takes such type has parameter so it makes sense to have such type.
> For a ReversibleCollection, i do not see many codes that will benefit taking a ReversibleCollection as parameter instead of using Collection.
It seems likely that many public APIs (both in the JDK and in external libraries)
will continue to use Collection, for compatibility reasons.
In certain cases (such as LinkedHashMap, see below) the APIs could be adjusted, if
the compatibility impact is small or can be mitigated.
ReversibleCollection unifies a broad set of existing collections without requiring
any retrofitting at all. Many applications and libraries don't have their own
collection implementations; they just use the ones in the JDK. They can benefit from
the new APIs in ReversibleCollection immediately, without the need for any
retrofitting at all.
ReversibleCollection also provide opportunities for new code and for existing APIs
that don't have stringent compatibility constraints. Consider an application that
has a method wants to consume an ordered collection; a reasonable API would take a
List as a parameter.
Suppose a caller happened to have a LinkedHashSet in the right order (for example,
because it wanted to deduplicate the elements). Either the caller would be forced to
copy the LHS into a List before passing it, or the callee could adjust its parameter
to be Collection -- but this creates the possibility of bugs if a HashSet is passed
by accident. Using ReversibleCollection as a parameter type fixes this problem.
>> * It's useful to have a new type for return types in APIs. Consider
>> LinkedHashMap's entrySet, keySet, and values views. While we clearly get by with
>> having these return Set or Collection today, we need a place to put the new
>> methods.
>> Either they go on Collection (and have extremely weak semantics) or we define
>> new
>> interfaces.
>
> Even if you define a new interface, you can not change the return type of LinkedHashMap entrySet because it's not a backward compatible change. LinkedHashMap is not final so you have to update all subclasses of LinkedHashMap too.
As I've mentioned, introducing the covariant overrides for LinkedHashMap views is a
compatibility *risk* but by itself this is not dispositive.
In the past we had no way to assess this risk, so we simply avoided ever making such
changes. This might be why NavigableMap introduced navigableKeySet to return a
NavigableSet instead of providing a covariant override for keySet.
If we can ascertain (via code searching) that introducing covariant overrides to
LinkedHashMap introduces minimal incompatibilities, we might decide to go ahead with
the change. (What's considered "minimal" is of course up for discussion.)
If however we decide the incompatibilities are too great, a fallback plan would be
to introduce new methods reversibleEntrySet() et al for the reversible views. This
would be a little bit disappointing, but it doesn't invalidate the
ReversibleCollection/ReversibleSet concept.
s'marks
More information about the core-libs-dev
mailing list