我有一个平面非规范化结构的传入对象,我从JDBC结果集实例化了它。传入对象镜像结果集,有大量重复数据,因此我希望将数据转换为具有嵌套子集合的父对象列表,即对象图或规范化列表。
传入对象的类如下所示:
class IncomingFlatItem {
String clientCode;
String clientName;
String emailAddress;
boolean emailHtml;
String reportCode;
String reportLanguage;
}
因此,传入的数据包含每个客户机的多个对象,我想将其聚合为一个客户机对象,其中包含客户机的电子邮件地址对象列表和报表对象列表。
因此,客户端对象将如下所示:
class Client {
String clientCode;
String clientName;
Set<EmailAddress> emailAddresses;
Set<Report> reports;
}
奇怪的是,我找不到一个现有的答案。我正在寻找嵌套流或链接流,但我希望找到最优雅的方法,并且我绝对希望避免for循环。
您可以使用映射函数来转换列表
Function<List<IncomingFlatItem>, Set<EmailAddress>> inferEmailAddress =
incomingFlatItems -> incomingFlatItems.stream()
.map(obj -> new EmailAddress(obj.getEmailAddress(),
obj.isEmailHtml()))
.collect(Collectors.toSet());
Function<List<IncomingFlatItem>, Set<Report>> inferReports =
incomingFlatItems -> incomingFlatItems.stream()
.map(obj -> new Report(obj.getReportCode(),
obj.getReportLanguage()))
.collect(Collectors.toSet());
进一步使用groupingBy
并将条目映射到列表
List<Client> transformIntoGroupedNormalisedContent(
List<IncomingFlatItem> incomingFlatItemList) {
return incomingFlatItemList.stream()
.collect(Collectors.groupingBy(inc ->
Arrays.asList(inc.getClientCode(), inc.getClientName())))
.entrySet()
.stream()
.map(e -> new Client(e.getKey().get(0),
e.getKey().get(1),
inferEmailAddress.apply(e.getValue()),
inferReports.apply(e.getValue())))
.collect(Collectors.toList());
}
您可以做的一件事是利用构造函数参数和流畅的API。考虑“嵌套”流和流API(带有动态数据)可能会很快变得复杂。
这只是使用一个fluentapi来简化事情(您可以使用一个合适的构建器模式)
class Client {
String clientCode;
String clientName;
Set<EmailAddress> emailAddresses = new HashSet<>();
Set<Report> reports = new HashSet<>();
public Client(String clientCode, String clientName) {
super();
this.clientCode = clientCode;
this.clientName = clientName;
}
public Client emailAddresses(String address, boolean html) {
this.emailAddresses =
Collections.singleton(new EmailAddress(address, html));
return this;
}
public Client reports(String... reports) {
this.reports = Arrays.stream(reports)
.map(Report::new)
.collect(Collectors.toSet());
return this;
}
public Client merge(Client other) {
this.emailAddresses.addAll(other.emailAddresses);
this.reports.addAll(other.reports);
if (null == this.clientName)
this.clientName = other.clientName;
if (null == this.clientCode)
this.clientCode = other.clientCode;
return this;
}
}
class EmailAddress {
public EmailAddress(String e, boolean html) {
}
}
class Report {
public Report(String r) {
}
}
和
Collection<Client> clients = incomingFlatItemsCollection.stream()
.map(flatItem -> new Client(flatItem.clientCode, flatItem.clientName)
.emailAddresses(flatItem.emailAddress, flatItem.emailHtml)
.reports(flatItem.reportCode, flatItem.reportLanguage))
.collect(Collectors.groupingBy(Client::getClientCode,
Collectors.reducing(new Client(null, null), Client::merge)))
.values();
或者,您也可以只使用映射函数将IncomingFlatItem
对象转换为客户端
。
你可以用这个:
List<Client> clients = items.stream()
.collect(Collectors.groupingBy(i -> Arrays.asList(i.getClientCode(), i.getClientName())))
.entrySet().stream()
.map(e -> new Client(e.getKey().get(0), e.getKey().get(1),
e.getValue().stream().map(i -> new EmailAddress(i.getEmailAddress(), i.isEmailHtml())).collect(Collectors.toSet()),
e.getValue().stream().map(i -> new Report(i.getReportCode(), i.getReportLanguage())).collect(Collectors.toSet())))
.collect(Collectors.toList());
开始时,您按clientCode
和clientName
对项目进行分组。然后将结果映射到客户机
对象。
确保。equals()
和hashCode()
方法用于EmailAddress
和Report
以确保它们在集合中是不同的。
我有下面的pojo 此employee类用于从mybatis orm获取对象列表(list)。 mybatis将输出作为列表返回,因为mybatis不支持将Map作为返回类型 我必须把它转换成地图 我尝试了下面的方法,但没有成功,因为它需要getName()和getId()方法 请告知是否有一种方法可以在不修改员工pojo的情况下使用stream实现。 注意:我知道我们可以使用ofr或for ea
问题内容: 有人知道有什么好的库可以将平面文件转换为Java对象吗?我发现了扁虫,但我正在寻找替代品。 问题答案: FFP-平面文件解析库 http://jffp.sourceforge.net/
我最近开始处理Java流。我试图从我的一个SQL查询的结果集中获取字符串值。结果集只从数据库中选择一个字符串/Varchar列。 所以我做了: 或: 我相信地图具有将数据从一种类型转换为另一种类型的功能。在本例中,从对象到字符串,然后在字符串列表中收集它们。 但上面的代码显示了编译时错误:无法从对象转换为字符串列表。 请给我建议正确的做法,并说明我的理解有什么问题。
问题内容: 我从服务器得到一个 json数组: 我想使用gson将上面的json数据转换为Java 对象。我尝试了以下方法: 首先,我创建了一个 Person.java 类: 然后,在服务类中,我执行了以下操作: 我收到异常 java.lang.ClassCastException:java.util.LinkedHashMap无法强制转换为Person 。如何摆脱我的问题?我只想将json数组转
问题内容: 如何转换 这是例子 有没有简单的方法可以做到这一点?什么库在这里有用? 谢谢。 问题答案: 也许http://dozer.sourceforge.net可以为您提供帮助。它是可通过xml配置的映射库。 我很快尝试了这个: 我的mappings.xml看起来像这样: 不幸的是,它仅将10映射到所有三个PojoObject属性。也许您可以看到错误并使用代码段。也许这是Dozer中的一个错误