【发布时间】:2019-06-18 13:23:24
【问题描述】:
给定需要排序和分组的对象列表:
static class Widget {
// ...
public String getCode() { return widgetCode; }
public String getName() { return widgetName; }
}
List<Widget> widgetList = Arrays.asList(
// several widgets with codes and names
);
我想将列表分组为一个列表列表,按 widgetCode 分组,每个子列表的元素按照它们在原始列表中遇到的顺序排列。我知道我可以使用groupingBy Collector 将它们分组到列表地图中:
Map<String,List<Widget>> widgetMap = widgetList.stream()
.collect(groupingBy(Widget::getCode));
我不认为键是排序的,所以我采取了额外的步骤,将整个内容加载到 SortedMap 类型中:
SortedMap<String,List<Widget>> sortedWidgetMap = new TreeMap<String,List<Widget>>(
widgetList.stream()
.collect(groupingBy(Widget::getCode))
);
我知道我可以使用 .values() 从 sortedWidgetMap 中获取一个集合,我猜它是一个有序集合,因为它来自一个有序的地图类型,所以这是我目前的解决方案:
Collection<List<Widget>> widgetListList = new TreeMap<String,List<Widget>>(
widgetList.stream()
.collect(groupingBy(Widget::getCode))
).values();
widgetListList.forEach(System.out::println); // do something with the data
到目前为止,这有效,但我不确定生成的 widgetListList 实际上是否保证顺序正确(即通过 widgetCode)或者子列表将构建在在原始列表中找到它们的顺序。另外,我认为必须可以单独使用 Stream API 来实现我想要的输出。那么,我怎样才能做得更好呢?
【问题讨论】:
-
对于排序,你可以给
TreeMap一个Comparator排序。 -
来自
SortedMap.values()的javadoc:“集合的迭代器以相应键的升序返回值。”,所以不用担心你的解决方案的顺序(虽然效率可能会提高) -
好吧,您可以向
groupingBy提供排序后的地图,例如喜欢这里:stackoverflow.com/questions/35116264/…
标签: java java-8 java-stream