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 — the history
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 — 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 AM 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 specified
> 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 violations.
>
> Peter
>
>
> On Sat, Jul 4, 2026 at 2:03 PM Gary Gregory <[email protected]> wrote:
>
> > On Sat, Jul 4, 2026 at 9:36 AM Elliotte Rusty Harold <[email protected]>
> > 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 PM Gary Gregory <[email protected]>
> > wrote:
> > > >
> > > > Hi All,
> > > >
> > > > Why do we have both Bag and MultiSet? They seem to do the same thing.
> > > >
> > > > 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]
> >
> >

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to