如何根据对象的值获取 10 个对象?

  • 本文关键字:对象 获取 何根 java
  • 更新时间 :
  • 英文 :


我必须创建一个方法,为整个系统中花费最多的 10 名纳税人提供方法。 已经创建了很多类,并且代码必须介于两者之间,但我需要的是:

public TreeSet<Taxpayer> getTenTaxpayers(){
TreeSet<Taxpayer> taxp = new TreeSet<Taxpayer>();
... 
for(Taxpayer t: this.taxpayers.values()){ //going through the Map<String, Taxpayer>
for(Invoice i: this.invoices.values()){ //going through the Map<String, Invoice>
if(taxp.size()<=10){ 
if(t.getTIN().equals(i.getTIN())){ //if the TIN on the taxpayer is the same as in the Invoice
...
}
}
}
}
return taxp;
}

总而言之,我必须通过一个Map<String, Taxpayer>,例如 100 名纳税人,然后为每张相应的发票进行Map<String, Invoice>,并根据发票类别上的 1 个属性返回一个新的集合,其中包含在整个系统上花费最多的 10 名纳税人。我的问题是我如何获得这 10 个,以及如何保持排序。我第一次看到它是使用带有比较器的树集,但问题是树集将与类纳税人一起使用,而我们需要比较的是类发票上的属性。

这是一个经典的Top K问题吗?也许你可以使用 java.util.PriorityQueue 来构建一个最小堆来获得前 10 名纳税人。

这可以分为 3 个步骤:

  • 提取不同的TaxPayer
  • 为每个付款人提取Invoice,然后汇总金额
  • 按支付金额排序,并限制为前 10

如果您使用的是java-8,则可以执行以下操作:

final Map<TaxPayer, Double> toTenMap = payersMap.values()                       // get values from map
.stream()                                                                   // create java.util.Stream
.distinct()                                                                 // do not process duplicates (TaxPayer must provide a standard-compliant equals method)
.map(taxPayer -> {
final double totalAmount = invoicesMap
.values()                                                           // get values from the invoices map
.stream()                                                           // create Stream
.filter(invoice -> invoice.getTIN().equals(taxPayer.getTIN()))      // get only those for the current TaxPayer
.mapToDouble(Invoice::getAmount)                                    // get amount
.sum();                                                             // sum amount
return new AbstractMap.SimpleEntry<>(taxPayer, totalAmount);            // create Map.Entry
})
.sorted( ( entry1, entry2 ) -> {                                            // sort by total amount
if (entry1.getValue() > entry2.getValue()) return 1;
if (entry1.getValue() < entry2.getValue()) return -1;
return 0;
})
.limit(10)                                                                  // get only top ten payers
.collect(Collectors.toMap(                                                  // save to map
AbstractMap.SimpleEntry::getKey,
AbstractMap.SimpleEntry::getValue
));

当然,有一个更优雅的解决方案。另外,我还没有测试它,因为我现在没有太多时间。

最新更新