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
。