Java 8 is featuring lambdas, which are similar to a construction Groovy has already for some time: closures.
In Groovy we could already do this:
def list = ['a', 'b', 'c']
print list.collect { it.toUpperCase() }
// [A, B, C]where { it.toUpperCase() } is the closure.
In Java 8 we can achieve the same functionality now in a concise way.
list.stream().map( s -> s.toUpperCase() )
Although you could argue that with proper use of the new Stream API, bulk operations and method references, at least the intent of a piece of code is conveyed more clearly now β Javaβs verboseness can still cause sore eyes.
Here are some other examples.
Some Groovy animals
class Animal {
String name
BigDecimal price
String farmer
String toString() { name }
}
def animals = []
animals << new Animal(name: "Buttercup", price: 2, farmer: "john")
animals << new Animal(name: "Carmella", price: 5, farmer: "dick")
animals << new Animal(name: "Cinnamon", price: 2, farmer: "dick")Example 1: Summing the total price of all animals
Groovy
assert 9 == animals.sum { it.price }
// or animals.price.sum()What Groovy you see here:
sumcan be called on a List and optionally passed a closure defining the property of βitβ β the animal being iterated over β to sort on.- or
sumcan be called on a List without any arguments, which is equivalent to invoking the βplusβ method on all items in the collection.
Java 8
Optional<BigDecimal> sum = animals. stream(). map(Animal::getPrice). reduce((l, r) -> l.add(r)); assert BigDecimal.valueOf(9) == sum.get();
What Java you see here:
- Through the Stream APIβs
streammethod we can create a pipeline of operations, such asmapandreduce - The argument to the
mapoperation is a method reference to thegetPrice()method of the currently iterated animal. We could also replace this part with the expressiona -> a.getPrice() reduceis a general reduction operation (also called a fold) in which theBigDecimalsof the prices are added up. This is also giving us anOptionalwith the total sum.- BTW, if we were to use a double for price β which we donβt because I want to give a good example β we could have used an existing DoubleStream with a
sum()on it e.g.double sum = animals.stream().mapToDouble(Animal::getPrice).sum();
Example 2: Grouping all animals by farmer
Groovy
def animalsByFarmer = animals.groupBy { it.farmer }
// [john:[Buttercup], dick:[Carmella, Cinnamon]]Java 8
Map<String, List<Animal>> animalsByFarmer =
animals
.stream()
.collect(
Collectors.groupingBy(Animal::getFarmer));
// {dick=[Carmella, Cinnamon], john=[Buttercup]}Example 3: Summing the total price of all animals grouped by farmer
Groovy
def totalPriceByFarmer =
animals
.groupBy { it.farmer }
.collectEntries { k, v -> [k, v.price.sum()] }
// [john:2, dick:7]What Groovy you see here:
collectEntriesiterates through the βgroupByβ map transforming each map entry using thek, v -> ...closure returning a map of the transformed entries.v.priceis actually a List of prices (per farmer) β such as in example 1 β on which we can callsum().
Java 8
Map<String, BigDecimal> totalPriceByFarmer =
animals
.stream()
.collect(
Collectors.groupingBy(
Animal::getFarmer,
Collectors.reducing(
BigDecimal.ZERO,
Animal::getPrice,
BigDecimal::add)));
// {dick=7, john=2}This Java code again yields the same results. Since IDEβs, Eclipse at least, donβt format this properly, youβll have to indent these kinds of constructions for readability a bit yourself.
| Reference: | Java 8 Lambdas vs Groovy Closures Compactness: Grouping And Summing from our JCG partner Ted Vinke at the Ted Vinkeβs Blog blog. |
Thank you!
We will contact you soon.

This site uses Akismet to reduce spam. Learn how your comment data is processed.