Java 按两个字段分组,然后求和BigDecimal

Java 按两个字段分组,然后求和BigDecimal,java,java-8,Java,Java 8,我有一份税单: 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 分类是 public class TaxLine { private BigDecimal price; private BigDecima

我有一份税单:

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
分类是

public class TaxLine {
    private BigDecimal price;
    private BigDecimal rate;
    private String title;
}
我想根据唯一的
标题
费率
将它们组合起来,然后添加
价格
,预计:

 TaxLine = title:"New York Tax", rate:0.20, price:40.00
 TaxLine = title:"County Tax", rate:0.10, price:10.00
如何在Java8中实现这一点


,不是对字段求和,它只能按两个字段进行分组。

无法对分组字段求和,可以通过定义一个名为TitleRate的新类别来实现,如下图所示

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

        }

        public TitleRate getTitleRate() {
            return new TitleRate(title, taxline);
        }
    }
要通过分组标题和税率对价格求和,可以使用下面的方法

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;
   }
Map groupedData=people.collect(Collectors.groupingBy(Taxline::gettitrate));
List groupedTaxLines=new ArrayList();
BigDecimal groupedRate=BigDecimal.ZERO;
对于(映射条目:groupedData.entrySet())
{
对于(Taxline Taxline:entry.getValue()){
groupedRate=groupedRate.add(taxline.getPrice());
}
添加(新的分类线(entry.getKey().getTitle,entry.getKey().getRate(),groupedRate));
groupedRate=BigDecimal.0;
}

一种方法是为要分组的字段集创建一个对象。这个类也可以用来提供很好的助手方法

所以,你最初的课程是这样完成的:

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;
    }
}
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));
    }
}
以及定义如下的分组帮助器类:

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;
    }
}
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));
    }
}
要制作此文件:

输入:
TaxLine=标题:“纽约税”,税率:0.20,价格:20.00
TaxLine=标题:“纽约税”,税率:0.20,价格:20.00
TaxLine=标题:“县税”,税率:0.10,价格:10.00
合并:
TaxLine=标题:“纽约税”,税率:0.20,价格:40.00
TaxLine=标题:“县税”,税率:0.10,价格:10.00

原理与链接问题中的相同,您只需使用不同的下游收集器来求和:

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());
List=taxes.stream()
.collect(收集器.groupingBy(
TaxLine::getTitle,
收集者分组(
TaxLine::getRate,
还原剂(
BigDecimal.ZERO,
TaxLine::getPrice,
BigDecimal::add)))
.entrySet()
.stream()
.flatMap(e1->e1.getValue()
.entrySet()
.stream()
.map(e2->新分类线(e2.getValue()、e2.getKey()、e1.getKey())
.collect(Collectors.toList());

srly,这会更详细吗?-\谢谢你的回答哈哈