假设我有一个来自DB的对象列表,格式如下
public class DBEvent {
private String guiEventId;
private String guiEventColor;
private int questionId;
private Date date;
// + Getters/setters...
}List<DBEvent>保存了以下内容,并重复了一些表格数据。我需要将所有条目按相同的GuiEventId/GuiEventColor分组,并拆分不同的QuestionId/Date。这可以是一个新的对象列表。

目标:
public class NewEvent {
private String guiEventId;
private String guiEventColor;
private Date date1;
private Date date2;
}换句话说,我需要捕获不同的日期(每对1/2行),同时保持其余的信息相同,并将其作为一个对象。
Java 8有一些流/过滤功能,它们在这里有帮助吗?还是我需要转到DB并重构我的SQL查询?
发布于 2017-12-27 21:19:02
可以根据从集合元素计算的值对项进行分组。例如,要按guiEventId对事件进行分组,可以调用:
List<DBEvent> events = ...//get events
Map<String, List<DBEvent>> groupedEvents =
events.stream().collect(Collectors.groupingBy(event -> event.getGuiEventId()));这将生成一个映射,其中包含映射到相应事件对象列表的所有遇到的事件ID。如果您确信事件ID和颜色是一致的,那么在分组键中包含颜色是多余的(尽管这很容易更改)。
现在,对于给定的事件对组,您要做的是将任意2元素列表转换为单个元素。为此,可以将值列表转换为新类型的事件:
//define a function that takes a list of events and produces a new event:
private NewEvent createNewEvent(List<DBEvent> events) {
NewEvent evt = new NewEvent();
evt.setGuiEventId(events.get(0).getGuiEventId());
evt.setGuiEventColor(events.get(0).getGuiEventColor());
evt.setDate1(events.get(0).getDate());
evt.setDate2(events.get(1).getDate());
return evt;
}现在,您只需将db事件列表映射的值集合中的值映射到NewEvent
List<NewEvent> newEvents =
groupedEvents.values().stream().map(eventList -> createNewEvent(eventList))
.collect(Collectors.toList());应注意以下几点:
Stream.reduce执行按对合并到新事件中的操作(但是,您必须在两个步骤中完成,以减少相同类型的产量)。https://stackoverflow.com/questions/47998505
复制相似问题