6

Is it possible to transform List<Entry> to Map<Employee, Map<LocalDate, Entry>> with one lambda expression?

public class Entry {
    Employee employee;
    LocalDate date;
}

So far i have came up with something like this:

entries.stream().collect(Collectors.toMap(Collectors.groupingBy(Entry::getEmployee), Collectors.groupingBy(Entry::getDate), Function.identity()));

But this gives a compilation error:

no suitable method found for 
toMap(java.util.stream.Collector<com.a.Entry,capture#1 of ?,java.util.Map<com.a.Employee,
java.util.List<com.a.Entry>>>‌​,java.util.stream.Co‌​llector<com.a.Entry,‌​capture#2 of ?, 
java.util.Map<java.time.LocalDate,java.util.List<com.a.Ent‌ry>>>,
java.util.func‌​tion.Function<java.l‌​ang.Object,java.lang‌​.Object>) 

Thanks

wvdz
  • 16,251
  • 4
  • 53
  • 90
przem
  • 164
  • 2
  • 9
  • Are you sure that Employee is a suitable key for a map? BTW, define "does not work". – aventurin Jan 17 '17 at 23:01
  • compilation error: no suitable method found for toMap(java.util.stream.Collector>>,java.util.stream.Collector>>,java.util.function.Function) – przem Jan 17 '17 at 23:07

1 Answers1

13

Assuming Entry has getters and Employee overrides hashCode() and equals():

Map<Employee, Map<LocalDate, Entry>> result = entries.stream()
        .collect(Collectors.groupingBy(Entry::getEmployee,
                Collectors.toMap(Entry::getDate, Function.identity())));

Note that this will throw an exception if an employee has duplicate dates.

shmosel
  • 49,289
  • 6
  • 73
  • 138
  • wicket, works perfectly. Exception on duplicates is expected behavior. Thank you – przem Jan 17 '17 at 23:12
  • And what if i'd need `Map>` where key for the map is Employee::getUsername ? Is it possible to manipulate the keys as well? – przem Jan 24 '17 at 21:41
  • 1
    @przem Sure, just replace `Entry::getEmployee` with `entry -> entry.getEmployee().getUsername()`. – shmosel Jan 24 '17 at 21:53
  • noooooo i cant be that simple!!! :-D many many thanks! works like a dream – przem Jan 24 '17 at 22:09