Java Streams:将List分组到Maps地图中

我如何使用Java Streams执行以下操作?

假设我有以下课程:

class Foo { Bar b; } class Bar { String id; String date; } 

我有一个List ,我想将它转换为Map <Foo.b.id, Map 。 即: 首先由Foo.b.id ,然后由Foo.b.date

我正在努力采用以下两步法,但第二步甚至没有编译:

 Map<String, List> groupById = myList .stream() .collect( Collectors.groupingBy( foo -> foo.getBar().getId() ) ); Map<String, Map> output = groupById.entrySet() .stream() .map( entry -> entry.getKey(), entry -> entry.getValue() .stream() .collect( Collectors.groupingBy( bar -> bar.getDate() ) ) ); 

提前致谢。

假设只有不同的Foo您可以一次性对数据进行分组:

 Map> map = list.stream() .collect(Collectors.groupingBy(f -> fbid, Collectors.toMap(f -> fbdate, Function.identity()))); 

使用静态导入保存一些字符:

 Map> map = list.stream() .collect(groupingBy(f -> fbid, toMap(f -> fbdate, identity()))); 

假设(b.id, b.date)对是不同的。 如果是这样,在第二步中你不需要分组,只需要收集到Map ,其中key是foo.b.date ,value是foo本身:

 Map> map = myList.stream() .collect(Collectors.groupingBy(f -> fbid)) // map {Foo.b.id -> List} .entrySet().stream() .collect(Collectors.toMap(e -> e.getKey(), // id e -> e.getValue().stream() // stream of foos .collect(Collectors.toMap(f -> fbdate, f -> f)))); 

或者更简单:

 Map> map = myList.stream() .collect(Collectors.groupingBy(f -> fbid, Collectors.toMap(f -> fbdate, f -> f))); 

另一种方法是在你的密钥Bar上支持平等合同:

 class Bar { String id; String date; public boolean equals(Object o){ if (o == null) return false; if (!o.getClass().equals(getClass())) return false; Bar other = (Bar)o; return Objects.equals(o.id, id) && Objects.equals(o.date, date); } public int hashCode(){ return id.hashCode*31 + date.hashCode; } } 

现在你可以有一个Map