假设我有一个来自数据库的对象列表,格式如下
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有一些流/过滤功能,它们会在这里有用吗?或者我是否需要转到数据库并重构我的SQL查询?
答案 0 :(得分:1)
您可以按照从集合元素计算的值对项目进行分组。例如,要按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
来执行成对合并到新事件中(但之后您必须在2中执行此操作)减少产生相同类型的步骤)