Eclipse Collections by Example: Min and Max

Donald Raab
3 min readJun 24, 2018

--

Learn how to find the minimum and maximum values in a collection using Eclipse Collections.

Of Max and Min

How do you find the min and max of a collection?

If you have a collection that contains Comparable values, you can simply use min and max with no parameters.

@Test
public void theMinAndTheMax()
{
MutableList<String> alphabet =
Lists.mutable.with("a", "b", "c", "d", "e");
String max = alphabet.max();
String min = alphabet.min();
Assert.assertEquals("e", max);
Assert.assertEquals("a", min);
}

Using Comparators

Alternatively, there are forms of min and max that take a Comparator as a parameter.

@Test
public void theComparators()
{
MutableList<String> alphabet =
Lists.mutable.with("a", "b", "c", "d", "e");
String max = alphabet.max(Comparators.reverseNaturalOrder());
String min = alphabet.min(Comparators.reverseNaturalOrder());
Assert.assertEquals("a", max);
Assert.assertEquals("e", min);
}

Using minBy and maxBy

There are methods named minBy and maxBy which take a Function as a parameter. The Function is turned into a Comparator for you.

@Test
public void byTheBy()
{
MutableList<String> strings =
Lists.mutable.with("1", "22", "333", "4444");
String max = strings.maxBy(String::length);
String min = strings.minBy(String::length);
Assert.assertEquals("4444", max);
Assert.assertEquals("1", min);
}

Getting min and max using SummaryStatistics

There are methods on RichIterable that are prefixed with summarize that return an appropriate instance of SummaryStatistics. The three SummaryStatistics types (Int, Long and Double) added in Java 8 have the methods getMin and getMax, which allow you to calculate the min and max in a single iteration. The summarize methods take a primitive Function as a parameter. There are four summarize methods (with a suffix of Int, Float, Long and Double).

@Test
public void theStatistics()
{
MutableList<Integer> alphabet =
Lists.mutable.with(2, -3, 4, -5);
IntSummaryStatistics stats =
alphabet.summarizeInt(i -> i * i);
Assert.assertEquals(4, stats.getMin());
Assert.assertEquals(25, stats.getMax());
}

Primitive min and max

Any primitive collection can give you the min and max values. The methods min and max will throw an Exception if the collection is empty. You can specify a default value to protect against the case of a collection being empty using minIfEmpty and maxIfEmpty.

@Test
public void primitiveMaxAndMin()
{
String string =
("The quick brown fox " +
"jumps over the lazy dog.").toLowerCase();
CharList chars =
Strings.asChars(string).select(Character::isLetter);
Assert.assertEquals('a', chars.min());
Assert.assertEquals('z', chars.max());
CharList emptyChars = Strings.asChars("");
Assert.assertEquals('a', emptyChars.minIfEmpty('a'));
Assert.assertEquals('z', emptyChars.maxIfEmpty('z'));
}

Primitive summaryStatistics

If you have a primitive Iterable, you can call summaryStatistics directly on it. The method summaryStatistics will return either an Int, Long, or DoubleSummaryStatistics instance. For byte, char, short and float iterables, this will result in a widening of the type. As you can see below, summaryStatistics for a CharList returns an IntSummaryStatistics instance.

@Test
public void primitiveSummaryStatistics()
{
String string =
("The quick brown fox " +
"jumps over the lazy dog.").toLowerCase();
CharList chars =
Strings.asChars(string).select(Character::isLetter);
IntSummaryStatistics stats = chars.summaryStatistics();
Assert.assertEquals('a', stats.getMin());
Assert.assertEquals('z', stats.getMax());
}

Optional min and max

The min and max methods will throw an Exception if the collection is empty. You can protect against this by using the methods named minOptional and maxOptional. There are also optional forms for maxBy and minBy named maxByOptional and minByOptional.

@Test
public void theOptionals()
{
MutableList<String> alphabet = Lists.mutable.empty();
Optional<String> max =
alphabet.maxOptional(Comparators.naturalOrder());
Optional<String> min =
alphabet.minOptional(Comparators.naturalOrder());
Assert.assertFalse(max.isPresent());
Assert.assertFalse(min.isPresent());
}

APIs covered in the examples

  1. min / max — find the minimum or maximum value in a collection of Comparable values.
  2. min / max with Comparator — find the minimum or maximum value in a collection using the specified Comparator.
  3. minBy / maxBy — find the minimum or maximum value in a collection using the specified Function.
  4. summarizeInt — returns an IntSummaryStatistics by applying the specified IntFunction to each element of the collection. There are also forms of summarize with a suffix of Float, Long or Double.
  5. min / max (CharList)
  6. minIfEmpty / maxIfEmpty (CharList)
  7. minOptional / maxOptional with Comparator — find the minimum or maximum value in a collection using the specified Comparator returning an Optional value.
  8. summaryStatistics — returns an appropriate SummaryStatistics instance for the primitive Iterable type.
  9. Strings.asChars — creates a CharAdapter wrapping the specified String.

Check out this presentation to learn more about the origins, design and evolution of the Eclipse Collections API.

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

--

--

Donald Raab

Java Champion. Creator of the Eclipse Collections OSS Java library (https://github.com/eclipse/eclipse-collections). Inspired by Smalltalk. Opinions are my own.