2017-01-13 26 views
5

tôi có một danh sách các loại thuế:Nhóm của hai lĩnh vực sau đó tổng hợp BigDecimal

TaxLine = title:"New York Tax", rate:0.20, price:20.00 
TaxLine = title:"New York Tax", rate:0.20, price:20.00 
TaxLine = title:"County Tax", rate:0.10, price:10.00 

lớp TaxLine là

public class TaxLine { 
    private BigDecimal price; 
    private BigDecimal rate; 
    private String title; 
} 

Tôi muốn kết hợp chúng trên cơ sở độc đáo titlerate, sau đó thêm price, dự kiến:

TaxLine = title:"New York Tax", rate:0.20, price:40.00 
TaxLine = title:"County Tax", rate:0.10, price:10.00 

Làm cách nào để thực hiện điều này trong Java 8?

, không được tổng hợp một trường, chỉ có thể nhóm theo hai trường.

Trả lời

8

Hiệu trưởng cũng giống như trong câu hỏi liên quan, bạn chỉ cần một nhà sưu tập ở hạ nguồn khác nhau để tổng hợp:

List<TaxLine> flattened = taxes.stream() 
    .collect(Collectors.groupingBy(
     TaxLine::getTitle, 
     Collectors.groupingBy(
      TaxLine::getRate, 
      Collectors.reducing(
       BigDecimal.ZERO, 
       TaxLine::getPrice, 
       BigDecimal::add)))) 
    .entrySet() 
    .stream() 
    .flatMap(e1 -> e1.getValue() 
     .entrySet() 
     .stream() 
     .map(e2 -> new TaxLine(e2.getValue(), e2.getKey(), e1.getKey()))) 
    .collect(Collectors.toList()); 
0

Không thể tổng hợp trường được nhóm có thể đạt được bằng cách xác định một lớp mới gọi là TitleRate bên trong lớp Taxline như dưới đây.

class Taxline{ 
     public static class TitleRate { 
      public TitleRate(String title, int taxline) { 
       ... 
      } 

     } 

     public TitleRate getTitleRate() { 
      return new TitleRate(title, taxline); 
     } 
    } 

Để tính giá bằng cách nhóm tiêu đề và thuế, bên dưới có thể được sử dụng.

Map<TitleRate, List<Taxline>> groupedData = people.collect(Collectors.groupingBy(Taxline::getTitleRate)); 

    List<Taxline> groupedTaxLines = new ArrayList<Taxline>(); 
    BigDecimal groupedRate = BigDecimal.ZERO; 
    for (Map<TitleRate, List<Taxline>> entry : groupedData.entrySet()) 
    { 
    for(Taxline taxline : entry.getValue()){ 
     groupedRate = groupedRate.add(taxline.getPrice()); 
    } 
    groupedTaxLines.add(new Taxline(entry.getKey().getTitle, entry.getKey().getRate(), groupedRate)); 
     groupedRate = BigDecimal.ZERO; 
    } 
0

Một cách là tạo đối tượng cho nhóm trường bạn đang nhóm theo. Lớp đó có thể được xây dựng để cung cấp các phương thức trợ giúp tốt đẹp.

Như vậy, với lớp ban đầu của bạn đã hoàn thành như thế này:

public final class TaxLine { 
    private String title; 
    private BigDecimal rate; 
    private BigDecimal price; 
    public TaxLine(String title, BigDecimal rate, BigDecimal price) { 
     this.title = title; 
     this.rate = rate; 
     this.price = price; 
    } 
    public String getTitle() { 
     return this.title; 
    } 
    public BigDecimal getRate() { 
     return this.rate; 
    } 
    public BigDecimal getPrice() { 
     return this.price; 
    } 
    @Override 
    public String toString() { 
     return "TaxLine = title:\"" + this.title + "\", rate:" + this.rate + ", price:" + this.price; 
    } 
} 

Và lớp helper nhóm được định nghĩa như thế này:

public final class TaxGroup { 
    private String title; 
    private BigDecimal rate; 
    public static TaxLine asLine(Entry<TaxGroup, BigDecimal> e) { 
     return new TaxLine(e.getKey().getTitle(), e.getKey().getRate(), e.getValue()); 
    } 
    public TaxGroup(TaxLine taxLine) { 
     this.title = taxLine.getTitle(); 
     this.rate = taxLine.getRate(); 
    } 
    public String getTitle() { 
     return this.title; 
    } 
    public BigDecimal getRate() { 
     return this.rate; 
    } 
    @Override 
    public int hashCode() { 
     return this.title.hashCode() * 31 + this.rate.hashCode(); 
    } 
    @Override 
    public boolean equals(Object obj) { 
     if (obj == null || getClass() != obj.getClass()) 
      return false; 
     TaxGroup that = (TaxGroup) obj; 
     return (this.title.equals(that.title) && this.rate.equals(that.rate)); 
    } 
} 

Mã của bạn để kết hợp các mục dòng được này, chia rẽ về nhiều các đường để giúp xem các phần khác nhau của nó:

List<TaxLine> lines = Arrays.asList(
     new TaxLine("New York Tax", new BigDecimal("0.20"), new BigDecimal("20.00")), 
     new TaxLine("New York Tax", new BigDecimal("0.20"), new BigDecimal("20.00")), 
     new TaxLine("County Tax" , new BigDecimal("0.10"), new BigDecimal("10.00")) 
); 
List<TaxLine> combined = 
     lines 
     .stream() 
     .collect(Collectors.groupingBy(TaxGroup::new, 
             Collectors.reducing(BigDecimal.ZERO, 
                  TaxLine::getPrice, 
                  BigDecimal::add))) 
     .entrySet() 
     .stream() 
     .map(TaxGroup::asLine) 
     .collect(Collectors.toList()); 

Sau đó bạn có thể in đầu vào/đầu ra:

System.out.println("Input:"); 
lines.stream().forEach(System.out::println); 
System.out.println("Combined:"); 
combined.stream().forEach(System.out::println); 

Để sản xuất này:

Input: 
TaxLine = title:"New York Tax", rate:0.20, price:20.00 
TaxLine = title:"New York Tax", rate:0.20, price:20.00 
TaxLine = title:"County Tax", rate:0.10, price:10.00 
Combined: 
TaxLine = title:"New York Tax", rate:0.20, price:40.00 
TaxLine = title:"County Tax", rate:0.10, price:10.00 
Các vấn đề liên quan