Re: [COLLECTIONS] Bag vs. MultiSet
Paul King <[email protected]> Sun, 5 Jul 2026 10:04:45 +1000
| Newsgroups | gmane.comp.jakarta.commons.devel |
|---|---|
| Message-ID | <CADRx3PPdoNEKwS9GsZEskf-SV=akVSMpYPP6-e6_m4x1Mhqh9w@mail.gmail.com> |
If there is appetite to finish the COLLECTIONS-567 work, I created: https://github.com/apache/commons-collections/pull/703 This would allow the entire Bag hierarchy to be eventually deprecated/removed with a clear migration path but I didn't add any deprecations as part of that PR. Cheers, Paul. On Sun, Jul 5, 2026 at 8:41=E2=80=AFAM Paul King <[email protected]= > wrote: > > AI's read: > > Subject: Re: Why do we have both Bag and MultiSet? > > Peter's guess is right, and there's no need to speculate =E2=80=94 the hi= story > is recorded in COLLECTIONS-567 [1], filed by Thomas himself in 2015. > Before 4.0 there was discussion about fixing Bag's Collection-contract > violations in place, but it was kept as-is to ease migration of older > code bases. MultiSet was then added in 4.1 as the compliant > alternative, with the stated intent that "the old Bag could then be > deprecated". So having both was a deliberate transition strategy; > the deprecation step just never happened. > > They're also not quite two names for the same thing as the code > stands. Bag deviates from Collection in four places (add() sometimes > returns false after changing the collection, remove() removes all > occurrences, and containsAll/removeAll/retainAll respect cardinality), > while MultiSet keeps the inherited methods compliant and moves the > cardinality-aware operations to explicit ones (getCount, add(E, int), > remove(Object, int), setCount). > > For what it's worth, the rest of the ecosystem converged on the > MultiSet design. Guava's Multiset keeps every Collection method > contract-compliant and offers Multisets.containsOccurrences/ > removeOccurrences/retainOccurrences for the cardinality-sensitive > variants. Eclipse Collections is the interesting data point: it kept > the *name* Bag but not the semantics =E2=80=94 its MutableBag extends > java.util.Collection, follows the standard contract, and puts > occurrence logic in dedicated methods (occurrencesOf, addOccurrences, > removeOccurrences, ...). So the naming isn't really the issue; the > contract is, and Bag's own javadoc warning ("Exercise caution when > using a bag as a Collection") is effectively an admission that it > can't safely be used as the type it declares. > > If there's appetite to finish what COLLECTIONS-567 started, two gaps > would need closing first: > > * There's no sorted MultiSet. Bag has SortedBag/TreeBag, but the > multiset package only contains HashMultiSet plus decorators, so > TreeBag users currently have nowhere to migrate. > * A migration note mapping the old semantics to explicit calls > (e.g. bag.remove(x) -> multiSet.setCount(x, 0)), and possibly > MultiSetUtils equivalents of Guava's occurrence-aware helpers, > which would preserve the one useful thing Bag's violations > provided, under honest names. > > A possible sequence: add SortedMultiSet/TreeMultiSet and the helpers > in a 4.x minor, cross-reference MultiSet from the Bag javadoc now, > deprecate Bag in a following minor, and remove it in 5.0. Given how > widely used Bag is, a generous deprecation window seems warranted, > but carrying both forever seems worse than finishing the transition > decided a decade ago. > > [1] https://issues.apache.org/jira/browse/COLLECTIONS-567 > > On Sun, Jul 5, 2026 at 6:53=E2=80=AFAM Peter Burka <[email protected]> wrote= : > > > > Note that Bag includes the following note which is absent from MultiSet= : > > > > > This interface violates the Collection contract. The behavior specifi= ed > > in many of these methods is not the same as the behavior specified by > > Collection. The non-compliant methods are clearly marked with > > "(Violation)". Exercise caution when using a bag as a Collection. > > > > The JavaDoc also indicates that Bag was added in 2.0 while MultiSet is > > since 4.1. My guess is that MultiSet is an attempt to fix these violati= ons. > > > > Peter > > > > > > On Sat, Jul 4, 2026 at 2:03=E2=80=AFPM Gary Gregory <garydgregory@gmail= .com> wrote: > > > > > On Sat, Jul 4, 2026 at 9:36=E2=80=AFAM Elliotte Rusty Harold <elharo@= ibiblio.org> > > > wrote: > > > > > > > > There's no good reason I can see to have both. Multiset and bag are > > > > different names for the same thing. > > > > > > > > Now if you're asking why this mistake was made in the first place, = I > > > > can speculate and the commit history might have some clues. > > > > > > The first commit for both interfaces is from Thomas Neidhart so maybe > > > he can clarify. > > > > > > Gary > > > > > > > > > > > On Thu, Jul 2, 2026 at 9:42=E2=80=AFPM Gary Gregory <garydgregory@g= mail.com> > > > wrote: > > > > > > > > > > Hi All, > > > > > > > > > > Why do we have both Bag and MultiSet? They seem to do the same th= ing. > > > > > > > > > > Gary > > > > > > > > > > -----------------------------------------------------------------= ---- > > > > > To unsubscribe, e-mail: [email protected] > > > > > For additional commands, e-mail: [email protected] > > > > > > > > > > > > > > > > > -- > > > > 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] > > > > > >