2017-06-20 72 views
4

希望有人能帮助我。我有以下结构的POJO:将一个嵌套的POJOs列表流式传输到另一个POJO列表

public class Invoice{ 

private String docNum; 
private String customer; 
private ArrayList<InvoiceDetails> invoiceDetails; 

/* Getters and setters*/ 
} 

并用以下

public class InvoiceDetails{ 

private String vatGroup; 
private Double vatAmount; 
private Double amount; 

/* Getters and setters*/ 
} 

另一个POJO再说我有第三个具有以下

public class VatType{ 

private String vatGroup; 
private Double vatAmount; 
private Double amount; 

/* Getters and setters*/ 
} 

我试图要做的是将的List减小为VatTypeList,按vatGroup分组。如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); 

预期的结果将是VatTypeList下列物品:

("S1",300.0,90.0) 
("S2",380.0,90.0) 
("A1",150.0,30.0) 

我怎样才能使用在一个stream拍这个名单。避免遍历Lists? 在此先感谢

+0

您是否检查Stream API? – Pelocho

+1

从'InvoiceDetailes'和'VatType'提取共同部分到'CommonClass'可能是一个好主意,那么你可以在'List '上做操作,而不必转换列表vica-versa? –

回答

2

您首先需要一个flatMap才能在您的列表中创建所有的所有Invoice流。之后,您可以减少获得合并方法的变体toMap。最后的Mapvalues()方法将得到一个CollectionVatType的:

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); 
+0

感谢马诺斯,它工作得很好! – pburgov

1

您可以使用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()); 
+0

谢谢ΦXocę웃Пepeúpa它不会影响价值。 – pburgov

0

您还可以使用dozer library如果这是在你的项目中常见的任务。

1

这里有一个办法做到这一点使用Java 8的的ListMap新功能,而流:

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实例,并结合两个merge方法VatType实例:

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()); 
+1

谢谢你Federico这是一个非常有趣的替代方式的流。 – pburgov

相关问题