A couple of tabulate/Tabulators.groupBy examples (original) (raw)

Raab, Donald Donald.Raab at gs.com
Wed Dec 26 11:14:02 PST 2012


It is a complex contrived example made that way to get students of our kata class thinking and combining multiple steps. The solution with our API today is not that bad IMO.

Simple:

MutableListMultimap<String, Customer> multimap = this.company.getCustomers().groupBy(Customer::getCity);

Complex:

MutableListMultimap<Double, Customer> multimap = this.company.getCustomers() .groupBy(customer -> customer.getOrders() .asLazy() .flatCollect(Order::getLineItems) .collectDouble(LineItem::getValue) .max());

It actually got better since groupBy was removed from Iterable/Collection, because we'll no longer have to cast the lambda to our Function.

> A more complex example.

This is kind of a weird example, since the synthetic key is a number. Another way to accomplish this, that might be more in line with real business usage, is by the equivalent of the old "mapped": Map<Customer, Double> largestLineItemByByCustomer = customers.stream().tabulate(mappedTo(c -> c.getOrders()...reduce())); This creates a map from Customer to your max order value reduction. If you then want a "top ten customers by largest transaction", you could do: largestLineItemByCustomer.entrySet() .stream() .sorted(Comparators.naturalOrderValues()) .limit(10) .map(Map.Entry::getKey) .forEach(...);

> > Before: > > Map<Double, Collection> multimap = this.company.getCustomers() > .stream() > .groupBy(customer -> > customer.getOrders() > .stream() > .flatMap((Block<? super LineItem> sink, Order element) -> {element.getLineItems().forEach(sink);}) > .map(LineItem::getValue) > .reduce(0.0, (x, y) -> Math.max(x,y)));



More information about the lambda-libs-spec-experts mailing list