The Occurrences of Occurrences

Keeping counts, and letting you use them for different purposes.

Image for post
Image for post
Part of my shot glass collection

I have collected shot glasses for the past three decades. I lost count of the number of shot glasses I have. I think it must be somewhere over 200 by now. I usually buy one when I visit a place for the first time. Friends and family have joined in over the years picking me up shot glasses from cool places they visit. Now if I created a Java class called ShotGlass, I could put all instances of them in a Bag and then I could answer all kinds of questions about them. I could count them by a lot of different attributes.

A Bag keeps counts for you. It can tell you the number of occurrences of something it contains. There are several methods available on Bag that allow you to query or manipulate the number of occurrences of something in a Bag. Here are all the occurrences methods that the MutableBag class in Eclipse Collections 9.1 will have once it is released.

Image for post
Image for post
The method collectWithOccurrences is the newest addition in 9.1.

The following Eclipse Collections code will programmatically show you the top occurrences of all of the methods that contain “occurrences” in MutableBag.

@Test
public void topOccurrencesOfOccurrences()
{
Lists.fixedSize.with(MutableBag.class.getMethods())
.asLazy()
.selectWith(this::methodContains, "occurrences")
.countBy(Method::getName)
.topOccurrences(4)
.each(System.out::println);
}

private boolean methodContains(Method method, String string)
{
return method.getName().toLowerCase().contains(string);
}

This code outputs:

selectByOccurrences:4
topOccurrences:2
bottomOccurrences:2
forEachWithOccurrences:1
setOccurrences:1
addOccurrences:1
occurrencesOf:1
collectWithOccurrences:1
removeOccurrences:1

Why does topOccurrences(4) return a List of size 9?

Here is an example of using the method collectWithOccurrences with a Bag of ShotGlass.

@Test
public void collectWithOccurrences()
{
Bag<ShotGlass> glasses = Bags.mutable.with(
new ShotGlass(Size.SMALL, "Orlando", "Florida", "USA",
"Disney World"),
new ShotGlass(
Size.SMALL, "Orlando", "Florida", "USA",
"Sea World"),
new ShotGlass(
Size.SMALL, "Orlando", "Florida", "USA",
"Universal Studios"),
new ShotGlass(
Size.MEDIUM, "Orlando", "Florida", "USA",
"Hard Rock Cafe")
);

Bag<String> byCity = glasses.countBy(ShotGlass::getCity);

Assert.assertEquals(
Bags.mutable.with(PrimitiveTuples.pair("Orlando", 4)),
byCity.collectWithOccurrences(
PrimitiveTuples::pair, Bags.mutable.empty()));

Bag<Size> bySize = glasses.countBy(ShotGlass::getSize);

Assert.assertEquals(
Bags.mutable.with(
PrimitiveTuples.pair(Size.SMALL, 3),
PrimitiveTuples.pair(Size.MEDIUM, 1)),
bySize.collectWithOccurrences(
PrimitiveTuples::pair, Bags.mutable.empty()));
}

The method collectWithOccurrences is passed each unique value with its count via an ObjectIntToObjectFunction. It is up to the developer to determine what to return from the ObjectIntToObjectFunction. In these two cases I opted to simply return an ObjectIntPair by using PrimitiveTuples::pair.

I have blogged previously about the prepositions By and With and their usefulness in API of Eclipse Collections. There is the potential for more By and With occurrences methods to be added to the API of Bag. There is an open issue requesting more occurrences methods on Bag. https://github.com/eclipse/eclipse-collections/issues/406. I would support adding both By and With versions of various methods if there are valid needs.

So it is still unknown how many methods with occurrences we will wind up adding to our Bag types. How many occurrences of occurrences methods do you need?

Eclipse Collections is open for contributions. If you like the library, you can let us know by starring it.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store