Java中基于属性的压缩ArrayList
我有对象的Java ArrayList,在比较unitPrice属性后,我希望将其压缩为数组中尽可能少的项 以下面的ArrayList为例Java中基于属性的压缩ArrayList,java,arraylist,collections,Java,Arraylist,Collections,我有对象的Java ArrayList,在比较unitPrice属性后,我希望将其压缩为数组中尽可能少的项 以下面的ArrayList为例 data = [ {itemName: "Apple", purchaseDate: "Jan 01 2017", purchasedQuantity: 10, unitPrice:10}, {itemName: "Apple", purchaseDate: "Feb 01 2017", purchasedQuantity: 12, unitPr
data = [
{itemName: "Apple", purchaseDate: "Jan 01 2017", purchasedQuantity: 10, unitPrice:10},
{itemName: "Apple", purchaseDate: "Feb 01 2017", purchasedQuantity: 12, unitPrice:10},
{itemName: "Apple", purchaseDate: "Mar 01 2017", purchasedQuantity: 14, unitPrice:15},
{itemName: "Apple", purchaseDate: "Apr 01 2017", purchasedQuantity: 16, unitPrice:15},
{itemName: "Apple", purchaseDate: "May 01 2017", purchasedQuantity: 18, unitPrice:10}
]
在上例0中,第1项和第4项的单价相同,其余两项的单价相同。我希望在添加购买数量后,将第0、第1和第4项压缩为一项,第2和第3项压缩为另一项
data = [
{itemName: "Apple", purchaseDate: "Jan 01 2017", purchasedQuantity: 40, unitPrice:10},
{itemName: "Apple", purchaseDate: "Mar 01 2017", purchasedQuantity: 30, unitPrice:15}
]
我尝试了以下代码
for(int i = 0; i < data.size(); i++){
int productQuantityInStock = 0;
for(int k = 0; k < data.size()-1; k++){
if((i != k+1) && (data.get(i).getunitPrice().equals(data.get(k+1).getunitPrice()))){
productQuantityInStock = Integer.parseInt(data.get(i).getpurchasedQuantity()) + Integer.parseInt(data.get(k + 1).getpurchasedQuantity());
data.get(i).setProductInStock(String.valueOf(productQuantityInStock));
data.remove(k + 1);
}
}
}
for(int i=0;i
但是我没有得到想要的结果。首先,当您对数据列表进行迭代时,您将无法修改它,因为它将抛出一个
ConcurrentModificationException
第二,合并项目时,采购日期应该是什么
第三,它可能有助于创建第二个数据结构来存储处理结果。它在计算上不会像您预期的那样复杂。例如,从单价到项目数据的映射,这样您就不必多次循环
第四,您可以尝试两次通过的方法:
首先,在对数据列表进行迭代时,您将无法修改它,因为它将抛出一个
ConcurrentModificationException
第二,合并项目时,采购日期应该是什么
第三,它可能有助于创建第二个数据结构来存储处理结果。它在计算上不会像您预期的那样复杂。例如,从单价到项目数据的映射,这样您就不必多次循环
第四,您可以尝试两次通过的方法:
就代码中的问题而言,这是一个典型的问题:在向前迭代的同时从列表中删除元素 这意味着当您删除元素
k+1
时,以前位于索引k+2
处的元素将成为索引k+1
处的新元素;然后递增k
,这样就不再检查该元素
这里最简单的修复方法就是反向迭代k
:
for(int k = data.size()-2; k >= 0; k--){
请注意,您总是使用k+1
,而不是k
,因此您可能会发现它更易于使用
for(int k = data.size()-1; k > 0; k--){
并将车身中的k+1
替换为k
这看起来像是一个使用流可以更好地解决的问题 按价格对项目进行分组,然后使用下游收集器对其进行聚合
Collection<Item> reduced = data.stream()
.collect(
Collectors.groupingBy(Item::getunitPrice),
Collectors.reducing((i, j) -> {
int productQuantityInStock = Integer.parseInt(i.getpurchasedQuantity()) + Integer.parseInt(j).getpurchasedQuantity());
i.setProductInStock(String.valueOf(productQuantityInStock));
return i;
})
.values();
Collection reduced=data.stream()
.收集(
Collector.groupingBy(项目::getunitPrice),
收集器。还原((i,j)->{
int-productQuantityInStock=Integer.parseInt(i.getpurchasedQuantity())+Integer.parseInt(j.getpurchasedQuantity());
i、 setProductInStock(String.valueOf(productQuantityInStock));
返回i;
})
.values();
(顺便提一下,将购买的数量和库存数量存储为流看起来不是一个好主意。如果您将它们解析为int,并存储int的字符串表示形式,为什么不使用int?关于代码中的问题,这是一个典型的问题:在向前迭代的同时从列表中删除元素 这意味着当您删除元素
k+1
时,以前位于索引k+2
处的元素将成为索引k+1
处的新元素;然后递增k
,这样就不再检查该元素
这里最简单的修复方法就是反向迭代k
:
for(int k = data.size()-2; k >= 0; k--){
请注意,您总是使用k+1
,而不是k
,因此您可能会发现它更易于使用
for(int k = data.size()-1; k > 0; k--){
并将车身中的k+1
替换为k
这看起来像是一个使用流可以更好地解决的问题 按价格对项目进行分组,然后使用下游收集器对其进行聚合
Collection<Item> reduced = data.stream()
.collect(
Collectors.groupingBy(Item::getunitPrice),
Collectors.reducing((i, j) -> {
int productQuantityInStock = Integer.parseInt(i.getpurchasedQuantity()) + Integer.parseInt(j).getpurchasedQuantity());
i.setProductInStock(String.valueOf(productQuantityInStock));
return i;
})
.values();
Collection reduced=data.stream()
.收集(
Collector.groupingBy(项目::getunitPrice),
收集器。还原((i,j)->{
int-productQuantityInStock=Integer.parseInt(i.getpurchasedQuantity())+Integer.parseInt(j.getpurchasedQuantity());
i、 setProductInStock(String.valueOf(productQuantityInStock));
返回i;
})
.values();
(顺便说一句,将购买的数量和库存数量存储为流看起来不是一个好主意。如果您将它们解析为int,并存储int的字符串表示形式,为什么不使用int呢?)在执行删除操作时,反向迭代列表。为什么不使用增强for loop?您得到了什么结果?您期望得到什么结果?@Charlie循环进行时,它会在某个点检查并删除自身。请使用一致的计算方案:您的第五项实际值