On Mon, Dec 15, 2025 at 7:15 PM sebb <[email protected]> wrote:
>
> On Sun, 14 Dec 2025 at 14:06, Gary Gregory <[email protected]> wrote:
> >
> > On Fri, Dec 12, 2025 at 7:17 AM Paul King <[email protected]> wrote:
> > >
> > > Okay, there doesn't seem to be a lot of interest, but I went ahead and
> > > created the PR anyway:
> > >
> > > https://github.com/apache/commons-collections/pull/665
> > >
> > > If the decision is to close the PR, at least future users wanting such
> > > functionality might find the discussion and find something useful in
> > > the PR for their own codebases.
> >
> > Hi All:
> >
> > The feature request and PR look good (after review) and fit in this
> > component's scope IMO.
> >
> > I plan on merging it unless there are valid technical objections.
>
> My concern is that this offers very little gain for a the extra
> maintenance needed.
Well, that is the PMC's call of course.
> Also, there are lots of other similar methods in 3rd party libraries
> such as Eclipse Collections.
> We don't have the resources to emulate them, nor should we do so.
Eclipse Collections is feature rich and it would be significant work
to emulate all of its features. I agree that isn't the right direction
for Commons Collections right now. I'll explain below where my
thinking came from for suggesting the "inverted" functionality.
> Given that it is not diifficult for users to create their own
> inverses, I am not convinced we should include it.
>
> I think we should only consider new features which are genuinely
> useful AND are not trivial for end users to implement correctly.
I recently did Groovy equivalents of all the examples in the book
Eclipse Collections Categorically[1]. I used JDK collections but was
also, out of interest, doing some Commons Collection and Guava
versions of some of the examples. My goal was to look for any missing
features in Groovy's collection handling methods with a similar
sentiment, i.e. looking for genuinely useful features that weren't
trivial to implement using Groovy's other features. Out of that
activity, Groovy added a groupByMany method. It was the only EC
feature, called groupByEach in its API, that couldn't easily be
implemented using existing Groovy features. Many Groovy applications
have collections of domain objects and groupByMany lets you use simple
predicates or method references for the kind of queries that would be
easy if you were using SQL but turn out to be cumbersome and
error-prone if doing long-hand. Multimaps are a good representation of
one-to-many relationships and such relationships are common. As it
turns out, the degenerative form of groupByMany/Each is invert/flip,
so it made sense for Groovy to also include that functionality, though
we retain the name groupByMany.
As part of all of that, my assessment of Commons Collections was that
grouping was a weak point compared with EC. With streams, most of the
grouping can be accommodated only slightly more verbosely, but the
groupByMany functionality isn't nice to implement using streams.
Rather than propose an equivalent to groupByMany, I thought just to
propose the degenerative form "inverted". If there was interest and
use of that, it might be worth considering the more elaborate case.
This is an example of Groovy's equivalent of "inverted" but just using
JDK vanilla collections (a by-hand multimap if you will):
// --------
var citiesLived = [
Alice: ['NY', 'LA'],
Bob: ['NY'],
Cara: ['LA', 'CHI']
]
var grouped = citiesLived.groupByMany() // equivalent to "inverted"
assert grouped == [
NY : ['Alice', 'Bob'],
LA : ['Alice', 'Cara'],
CHI : ['Cara']
]
// --------
Here is an example of the more general form:
// --------
record Person(String name, List<String> cities) { }
var people = [
new Person('Alice', ['NY', 'LA']),
new Person('Bob', ['NY']),
new Person('Cara', ['LA', 'CHI'])
]
var grouped = people.groupByMany(Person::name, Person::cities)
assert grouped == [
NY : ['Alice', 'Bob'],
LA : ['Alice', 'Cara'],
CHI : ['Cara']
]
// --------
For Groovy, there are tens (or hundreds) of thousands of Grails
applications that use domain objects and need to do query-like
operations on such collections. I don't really know whether folks use
ORMs in combination with Commons Collections, but if that did seem
useful, it wouldn't be as trivial to implement as the degenerate
inverted form.
Cheers, Paul.
[1]
https://www.amazon.com/Eclipse-Collections-Categorically-Level-programming/dp/B0DZVK69D3
> > Gary
> >
> > >
> > > Cheers, Paul.
> > >
> > > On Fri, Dec 12, 2025 at 8:54 PM Paul King <[email protected]>
> > > wrote:
> > > >
> > > > On Fri, Dec 12, 2025 at 8:39 PM sebb <[email protected]> wrote:
> > > > >
> > > > > On Thu, 11 Dec 2025 at 23:49, Paul King <[email protected]>
> > > > > wrote:
> > > > > >
> > > > > > True, I guess an analysis of the above suggested searches could
> > > > > > reveal, in some cases, the sizes of the data and why the dozens or
> > > > > > hundreds of cases mentioned above chose to use the flip/inver**
> > > > > > methods instead of double storing the datasets. I would think small
> > > > > > immutable datasets could be suitable for double storing. For large
> > > > > > datasets, the storage requirements might be problematic. For mutable
> > > > > > sets, the double manipulations for a putAll (as one example) can
> > > > > > become messy.
> > > > >
> > > > > AFAICT, Eclipse Collections flip creates a new Map with the keys and
> > > > > values reversed.
> > > > > So no saving in storage.
> > > >
> > > > Certainly that would be true for cases where both the normal and the
> > > > inverse maps were always both needed and were created and used in a
> > > > short time span. In the scenarios I am using multimaps, the normal
> > > > data is more long-lived, and the inverse is only needed occasionally
> > > > when the user asks for certain "query" operations.
> > > >
> > > > > > Cheers, Paul.
> > > > > >
> > > > > > On Fri, Dec 12, 2025 at 8:19 AM sebb <[email protected]> wrote:
> > > > > > >
> > > > > > > On Thu, 11 Dec 2025 at 20:57, Paul King
> > > > > > > <[email protected]> wrote:
> > > > > > > >
> > > > > > > > Well, I can just give you one user (multiple instances in the
> > > > > > > > codebase) that I know of which is why I brought it up. I don't
> > > > > > > > know
> > > > > > > > anyone else using Commons Collections in their projects. Many
> > > > > > > > projects
> > > > > > > > I am involved in use Groovy which has some nicer workarounds
> > > > > > > > than the
> > > > > > > > stream variant I mentioned earlier. So, it's less critical for
> > > > > > > > me, but
> > > > > > > > I thought Java users would appreciate the simpler form.
> > > > > > > >
> > > > > > > > Asking ChatGPT about Eclipse Collections flip() usage and
> > > > > > > > inverse()
> > > > > > > > and invertFrom() for Guava points to Minecraft and Eclipse
> > > > > > > > Xtext as
> > > > > > > > quick examples of usage. It goes on to say:
> > > > > > > >
> > > > > > > > > How to find more examples yourself
> > > > > > > > >
> > > > > > > > > Use GitHub code search (or grep over downloaded repos) with
> > > > > > > > > queries like:
> > > > > > > > >
> > > > > > > > > Multimaps.invertFrom(
> > > > > > > > > invertFrom( + Multimap
> > > > > > > > > flip() + org.eclipse.collections (or search for
> > > > > > > > > Multimap.flip())
> > > > > > > > >
> > > > > > > > > Those queries will turn up dozens — often hundreds — of
> > > > > > > > > usages across OSS.
> > > > > > > >
> > > > > > >
> > > > > > > However, if you know that you will need the inverse, it's not
> > > > > > > difficult to build that in parallel.
> > > > > > >
> > > > > > > Are there any occasions where the inverse has to be built later
> > > > > > > from
> > > > > > > an existing Multimap?
> > > > > > >
> > > > > > > > Cheers, Paul.
> > > > > > > >
> > > > > > > >
> > > > > > > > On Fri, Dec 12, 2025 at 1:23 AM Elliotte Rusty Harold
> > > > > > > > <[email protected]> wrote:
> > > > > > > > >
> > > > > > > > > On Thu, Dec 11, 2025 at 3:06 PM Gilles Sadowski
> > > > > > > > > <[email protected]> wrote:
> > > > > > > > > >
> > > > > > > > > > Hello.
> > > > > > > > >
> > > > > > > > > > Isn't it a "chicken-and-egg" question?
> > > > > > > > > > Isn't the purpose of a "common" library to implement
> > > > > > > > > > well-defined and
> > > > > > > > > > generally useful functionality, in the hope that it'll
> > > > > > > > > > incite code reuse?
> > > > > > > > > > Until said functionality is implemented, it obviously
> > > > > > > > > > cannot be used...
> > > > > > > > >
> > > > > > > > > No, it isn't. The use case comes first. If you can point to
> > > > > > > > > three
> > > > > > > > > existing projects that have had to implement this
> > > > > > > > > functionality
> > > > > > > > > already, and that would be willing to replace their existing
> > > > > > > > > code with
> > > > > > > > > a common library, then you have a case for implementing it
> > > > > > > > > here.
> > > > > > > > > Absent that, it is unlikely it will be adopted broadly enough
> > > > > > > > > to be
> > > > > > > > > worth the effort.
> > > > > > > > >
> > > > > > > > > --
> > > > > > > > > Elliotte Rusty Harold
> > > > > > > > > [email protected]
> > > > > > > > >
> > > > > > > > > ---------------------------------------------------------------------
> > > > > > > > > To unsubscribe, e-mail: [email protected]
> > > > > > > > > For additional commands, e-mail: [email protected]
> > > > > > > > >
> > > > > > > >
> > > > > > > > ---------------------------------------------------------------------
> > > > > > > > To unsubscribe, e-mail: [email protected]
> > > > > > > > For additional commands, e-mail: [email protected]
> > > > > > > >
> > > > > > >
> > > > > > > ---------------------------------------------------------------------
> > > > > > > To unsubscribe, e-mail: [email protected]
> > > > > > > For additional commands, e-mail: [email protected]
> > > > > > >
> > > > > >
> > > > > > ---------------------------------------------------------------------
> > > > > > To unsubscribe, e-mail: [email protected]
> > > > > > For additional commands, e-mail: [email protected]
> > > > > >
> > > > >
> > > > > ---------------------------------------------------------------------
> > > > > To unsubscribe, e-mail: [email protected]
> > > > > For additional commands, e-mail: [email protected]
> > > > >
> > >
> > > ---------------------------------------------------------------------
> > > To unsubscribe, e-mail: [email protected]
> > > For additional commands, e-mail: [email protected]
> > >
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: [email protected]
> > For additional commands, e-mail: [email protected]
> >
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [email protected]
> For additional commands, e-mail: [email protected]
>
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]