嵌套的 POJO 列表流到另一个 POJO 列表
Stream of a nested POJOs List to a another POJO LIST
希望有人能帮助我。我有一个具有以下结构的 POJO:
public class Invoice{
private String docNum;
private String customer;
private ArrayList<InvoiceDetails> invoiceDetails;
/* Getters and setters*/
}
还有另一个 POJO 具有以下内容
public class InvoiceDetails{
private String vatGroup;
private Double vatAmount;
private Double amount;
/* Getters and setters*/
}
另外还有第三个
public class VatType{
private String vatGroup;
private Double vatAmount;
private Double amount;
/* Getters and setters*/
}
我想做的是将 Invoice
中的 List
减少为按 vatGroup 分组的 List
中的 VatType
。就像 SQL
中的 de DISTINCT
子句。
假设我有以下列表:
InvoiceDetails idA1 = new InvoiceDetails("S1", 100.0, 40.0);
InvoiceDetails idA2 = new InvoiceDetails("S2", 140.0, 40.0);
InvoiceDetails idA3 = new InvoiceDetails("A1", 50.0, 10.0);
ArrayList<InvoiceDetails> listA = new ArrayList<>();
listA.add(idA1);
listA.add(idA2);
listA.add(idA3);
Invoice invoiceA = new Invoice();
invoiceA.setDetailList(listA);
InvoiceDetails idB1 = new InvoiceDetails("S1", 200.0, 50.0);
InvoiceDetails idB2 = new InvoiceDetails("S2", 240.0, 50.0);
InvoiceDetails idB2 = new InvoiceDetails("A1", 100.0, 20.0);
ArrayList<InvoiceDetails> listB = new ArrayList<>();
listB.add(idB1);
listB.add(idB2);
listB.add(idB3);
Invoice invoiceB = new Invoice();
invoiceB.setDetailList(listB);
List<Invoice> invoiceList = new ArrayList<>();
invoiceList.add(invoiceA);
invoiceList.add(invoiceB);
预期结果将是 List
的 VatType
,其中包含以下项目:
("S1",300.0,90.0)
("S2",380.0,90.0)
("A1",150.0,30.0)
如何使用 stream
一次获得此列表。避免遍历 Lists
?
提前致谢
您首先需要一个获取合并方法的 flatMap to create a stream of all InvoiceDetails
in all Invoice
in your list. After that you can reduce with the variant of toMap。最后 Map
的 values()
方法将得到 VatType
的 Collection
:
Collection<VatType> values = invoiceList.stream()
.flatMap(invoices -> invoices.getInvoiceDetails().stream())
.collect(toMap(InvoiceDetails::getVatGroup, VatType::new, (i1, i2) -> {
i1.setAmount(i1.getAmount() + i2.getAmount());
i1.setVatAmount(i1.getVatAmount() + i2.getVatAmount());
return i1;
}))
.values();
使用此 VatType
构造函数的位置:
VatType(InvoiceDetails invoiceDetails) {
vatGroup = invoiceDetails.getVatGroup();
vatAmount = invoiceDetails.getVatAmount();
amount = invoiceDetails.getAmount();
}
如果需要,您可以轻松地从 Collection
制作 List
:
List<VatType> vatTypes = new ArrayList<>(values);
您可以使用Java流功能:
Function<InvoiceDetails, VatType> myF = t -> new VatType(t.getVatGroup(), t.getVatAmount(), t.getAmount());
然后使用流式传输:
List<VatType> myLocations =
invoiceList.stream()
.map(Invoice::getInvoiceDetails)
.flatMap(Collection::stream)
.map(myF)
.collect(Collectors.<VatType>toList());
如果这是您项目中的常见任务,您也可以使用 dozer library。
这是一种使用 Java 8 的 List
和 Map
新功能的方法,无需流:
Map<String, VatType> map = new HashMap<>();
invoiceList.forEach(i -> i.getDetailList().forEach(d ->
map.merge(
d.getVatGroup(),
new VatType(d.getVatGroup(), d.getVatAmount(), d.getAmount()),
(left, right) -> {
left.setAmount(left.getAmount() + right.getAmount());
left.setVatAmount(left.getVatAmount() + right.getVatAmount());
return left;
})));
List<VatType> result = new ArrayList<>(map.values());
如果您可以向 VatType
添加一个接受 InvoiceDetail
实例的构造函数和一个组合两个 VatType
实例的 merge
方法:
public VatType(String vatGroup, Double vatAmount, Double amount) {
this.vatGroup = vatGroup;
this.vatAmount = vatAmount;
this.amount = amount;
}
public VatType(InvoiceDetails details) {
this(details.getVatGroup(), details.getVatAmount(), details.getAmount());
}
public VatType merge(VatType another) {
this.vatAmount += another.vatAmount;
this.amount += another.amount;
return this;
}
然后,您可以将第一个片段简化为:
Map<String, VatType> map = new HashMap<>();
invoiceList.forEach(i -> i.getDetailList().forEach(d ->
map.merge(d.getVatGroup(), new VatType(d), VatType::merge)));
List<VatType> result = new ArrayList<>(map.values());
希望有人能帮助我。我有一个具有以下结构的 POJO:
public class Invoice{
private String docNum;
private String customer;
private ArrayList<InvoiceDetails> invoiceDetails;
/* Getters and setters*/
}
还有另一个 POJO 具有以下内容
public class InvoiceDetails{
private String vatGroup;
private Double vatAmount;
private Double amount;
/* Getters and setters*/
}
另外还有第三个
public class VatType{
private String vatGroup;
private Double vatAmount;
private Double amount;
/* Getters and setters*/
}
我想做的是将 Invoice
中的 List
减少为按 vatGroup 分组的 List
中的 VatType
。就像 SQL
中的 de DISTINCT
子句。
假设我有以下列表:
InvoiceDetails idA1 = new InvoiceDetails("S1", 100.0, 40.0);
InvoiceDetails idA2 = new InvoiceDetails("S2", 140.0, 40.0);
InvoiceDetails idA3 = new InvoiceDetails("A1", 50.0, 10.0);
ArrayList<InvoiceDetails> listA = new ArrayList<>();
listA.add(idA1);
listA.add(idA2);
listA.add(idA3);
Invoice invoiceA = new Invoice();
invoiceA.setDetailList(listA);
InvoiceDetails idB1 = new InvoiceDetails("S1", 200.0, 50.0);
InvoiceDetails idB2 = new InvoiceDetails("S2", 240.0, 50.0);
InvoiceDetails idB2 = new InvoiceDetails("A1", 100.0, 20.0);
ArrayList<InvoiceDetails> listB = new ArrayList<>();
listB.add(idB1);
listB.add(idB2);
listB.add(idB3);
Invoice invoiceB = new Invoice();
invoiceB.setDetailList(listB);
List<Invoice> invoiceList = new ArrayList<>();
invoiceList.add(invoiceA);
invoiceList.add(invoiceB);
预期结果将是 List
的 VatType
,其中包含以下项目:
("S1",300.0,90.0)
("S2",380.0,90.0)
("A1",150.0,30.0)
如何使用 stream
一次获得此列表。避免遍历 Lists
?
提前致谢
您首先需要一个获取合并方法的 flatMap to create a stream of all InvoiceDetails
in all Invoice
in your list. After that you can reduce with the variant of toMap。最后 Map
的 values()
方法将得到 VatType
的 Collection
:
Collection<VatType> values = invoiceList.stream()
.flatMap(invoices -> invoices.getInvoiceDetails().stream())
.collect(toMap(InvoiceDetails::getVatGroup, VatType::new, (i1, i2) -> {
i1.setAmount(i1.getAmount() + i2.getAmount());
i1.setVatAmount(i1.getVatAmount() + i2.getVatAmount());
return i1;
}))
.values();
使用此 VatType
构造函数的位置:
VatType(InvoiceDetails invoiceDetails) {
vatGroup = invoiceDetails.getVatGroup();
vatAmount = invoiceDetails.getVatAmount();
amount = invoiceDetails.getAmount();
}
如果需要,您可以轻松地从 Collection
制作 List
:
List<VatType> vatTypes = new ArrayList<>(values);
您可以使用Java流功能:
Function<InvoiceDetails, VatType> myF = t -> new VatType(t.getVatGroup(), t.getVatAmount(), t.getAmount());
然后使用流式传输:
List<VatType> myLocations =
invoiceList.stream()
.map(Invoice::getInvoiceDetails)
.flatMap(Collection::stream)
.map(myF)
.collect(Collectors.<VatType>toList());
如果这是您项目中的常见任务,您也可以使用 dozer library。
这是一种使用 Java 8 的 List
和 Map
新功能的方法,无需流:
Map<String, VatType> map = new HashMap<>();
invoiceList.forEach(i -> i.getDetailList().forEach(d ->
map.merge(
d.getVatGroup(),
new VatType(d.getVatGroup(), d.getVatAmount(), d.getAmount()),
(left, right) -> {
left.setAmount(left.getAmount() + right.getAmount());
left.setVatAmount(left.getVatAmount() + right.getVatAmount());
return left;
})));
List<VatType> result = new ArrayList<>(map.values());
如果您可以向 VatType
添加一个接受 InvoiceDetail
实例的构造函数和一个组合两个 VatType
实例的 merge
方法:
public VatType(String vatGroup, Double vatAmount, Double amount) {
this.vatGroup = vatGroup;
this.vatAmount = vatAmount;
this.amount = amount;
}
public VatType(InvoiceDetails details) {
this(details.getVatGroup(), details.getVatAmount(), details.getAmount());
}
public VatType merge(VatType another) {
this.vatAmount += another.vatAmount;
this.amount += another.amount;
return this;
}
然后,您可以将第一个片段简化为:
Map<String, VatType> map = new HashMap<>();
invoiceList.forEach(i -> i.getDetailList().forEach(d ->
map.merge(d.getVatGroup(), new VatType(d), VatType::merge)));
List<VatType> result = new ArrayList<>(map.values());