A couple of tabulate/Tabulators.groupBy examples

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<Customer>> 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-observers mailing list