bounty将在4天后过期。回答此问题可获得+50的声誉奖励。mattsmith5正在寻找来自声誉良好来源的答案。
我有一个ProductTransactions列表。我想找到List<ProductTransaction>
中每个产品的最终(最大)productTransactionId销售。因此,我按ProductId对其进行分区,并按ProductTransactionId排序。下面示例中的最终列表List<Integer> (2, 5, 9)
如何完成?我正在尝试使用流和过滤器。
@Data
public class ProductTransaction {
private int productTransactionId;
private int productId;
private Date saleDate;
private BigDecimal amount;
}
| 产品交易ID|产品ID|销售日期|金额|
| - ------|- ------|- ------|- ------|
| 1个|1个|2019年3月2日|五个|
| 第二章|1个|2019年4月1日|九|
| 三个|第二章|2019年4月1日|第二章|
| 四个|第二章|2019年8月21日|三个|
| 五个|第二章|2019年8月21日|四个|
| 六个|三个|2019年10月1日|第二章|
| 七|三个|2019年10月3日|五个|
| 八个|三个|2019年10月3日|七|
| 九|三个|2019年10月3日|八个|
(请忽略销售日期,只按产品交易Id排序;表输入数据可能不需要排序
当前正在使用Java 8
尝试:
当前的长解决方案(希望使短手更干净,或者性能更快)
Set<Long> finalProductTransactionIds = new HashSet<>();
Set<Long> distinctProductIds = productTransactions.stream()
.map(ProductTransaction::getProductid)
.collect(Collectors.toSet());
for (Long productId: distinctProductIds) {
Long productTransactionId = productTransactions.stream()
.filter(x -> x.getProductId() == productId])
.sorted(Comparator.comparing(ProductTransaction::getProductTransactionId)
.reversed())
.collect(Collectors.toList()).get(0).getProductTransactionId();
finalProductTransactionIds.add(productTransactionId);
}
7条答案
按热度按时间ovfsdjhp1#
如果你不介意打开Optionals,你可以根据你的产品ID分组,然后使用mapping + maxBy下游收集器,这样就避免了收集到临时列表,因为只会保留最后一个项目(但是为可选示例增加了最小的开销)。
还可以使用
toMap
收集器的特殊重载来避免Optional类型:感谢Eritrean指出
getProductId
返回一个int,所以我们可以用较短的Math::max
(Math#max(int,int)
)方法引用替换通常适用的BinaryOperator.maxBy(Comparator.naturalOrder)
,它将返回两个整数中较大的值:也许你不喜欢Stream API,你可以使用一个常规循环和
Map#merge
函数来实现同样的最终结果,如果你眯着眼睛看,merge调用甚至看起来像toMap
收集器(为什么这样,留给读者作为练习:)。它绝对避免了创建流和收集器对象(无论如何,这很少是个问题)。
czfnxgou2#
在列表中进行流式传输,并使用
productId
作为键,productTransactionId
作为值收集到map。如果一个或多个对象共享同一个productId
,则使用Math::max
获取productTransactionId
最大的对象,并获得map的值:q1qsirdb3#
您可以通过一些收集器和grouping by来实现它。您可以参考以下有用的article
jhdbpxl94#
使用流
[二、五、九]
cwdobuhd5#
简单点!
记住,代码的支持比实现要复杂得多。最好用多一点的行来写smth.,但是要清楚得多。
例如
Streams
是相当高效的,但是有时候要实现它是如何工作的要复杂得多。如果你可以不使用它来写smth,请考虑一下。也许它会比流更清晰。x6492ojm6#
如果您对第三方库持开放态度,StreamEx提供了一些很好的助手来进行更高级的转换:
shstlldc7#
流到一个Map中,在所需的键(在您的例子中是productId)上累积,但当您遇到同一个键的多个值时,在Map合并上按最大数量解析-下面的BinaryOperator.maxBy。
打印:[2、5、9]