遍历对象的arraylist并从重复的对象中获取最大数量值

时间:2017-08-22 07:34:45

标签: java android arraylist collections

所以我有这个Product对象的ArrayList。我正在做的是点击+按钮,我正在创建一个Product对象并设置ui的所有属性;包括'数量'并将此对象添加到ArrayList。现在,由于我在单击+按钮时添加了一个对象,因此我获得了具有所有相同属性的重复Product对象,当然,' quantity'计数。如果我添加一个数量为4的产品,我会在arraylist中获得4个不同数量1,2,3和4的Product对象。我只想在集合中包含具有最大数量的Product对象。我使用Comparator来解决这个问题,但我在这里做错了。请帮助找出我做错了什么。谢谢。这是产品的模型,其中getter和setter从代码段中排除。

产品:

private String category;
private String code;
private String description;
private String units;
private String weight;
private Integer tax;
private String pieces;
private Integer aliasFlag;
private Double price;
private Integer quantity;
private Integer taxAmount;
private Double totalAmount;

到目前为止,我使用Comparator比较两个或更多(根据数量计算)Product的对象是:

Collections.sort(mProductsToBeSent, new Comparator<Products>() {
                @Override
                public int compare(Products ob1, Products ob2) {
                    if (ob1.getCode().equals(ob2.getCode())) {
                        if (ob1.getQuantity()<ob2.getQuantity()){
                            mProductsToBeSent.remove(ob1);
                        }
                    }
                    return 0;
                }
            });

mProductToBeSent是我的ArrayList,我必须作为Json发送,但由于存在重复,这不会做。我正在比较代码&#39;同一产品的两个后续对象的属性,如果它是真的,那么我将比较&#39;数量&#39;。如果它是真的那么我从列表中删除较小数量的对象。但我没有得到理想的输出。

我现在得到的输出:

  

[
  产品{Aliasflag =&#39; 0&#39;,代码=&#39; BMA10K&#39;,描述= abc,价格= 270.0,数量= 1,Taxamount = 0,单位=&#39; BAGS&#39; },
  产品{Aliasflag =&#39; 0&#39;,代码=&#39; BMA10K&#39;,描述= def,价格= 270.0,数量= 2,Taxamount = 0,Units =&#39; BAGS&#39; },
  产品{Aliasflag =&#39; 0&#39;,Code =&#39; BMA10K&#39 ;, Description = ghi,Price = 270.0,Quantity = 3,Taxamount = 0,Units =&#39; BAGS&#39; },
  产品{Aliasflag =&#39; 0&#39;,代码=&#39; BMA10K&#39;,描述= jkl,价格= 270.0,数量= 4 ,Taxamount = 0,Units =& #39;包袋&#39;}
]

正如您所看到的,我尝试删除要删除的前三个对象,并仅在arraylist中保留最大数量的对象;这是第四个对象 - 在这种情况下。

期望的输出:

  

[
  产品{Aliasflag =&#39; 0&#39;,代码=&#39; BMA10K&#39;,描述= jkl,价格= 270.0,数量= 4 ,Taxamount = 0,Units =& #39;包袋&#39;}
]

3 个答案:

答案 0 :(得分:2)

通常的做法是不使用其他数量值将不同的产品添加到列表中,而是将产品从列表中取出并更新其数量。

写作答案,因为我不能只评论,我认为它会对你有帮助。

答案 1 :(得分:1)

您可以这样做:

mProductsToBeSent.stream()
      .collect(Collectors.groupingBy(Product::getCode,
               Collectors.maxBy(Comparator.comparing(Category::getQuantity))));

您将获得地图Map<String, Optional<Product>>,现在可以通过这种方式将其转换为List

yourObtainedMap.entrySet()
     .stream().map(entry -> entry.getValue().get())
     .collect(Collectors.toList())

答案 2 :(得分:1)

您在排序时无法从列表中删除元素。

我会这样做比较:

new Comparator<Products>() {
                @Override
                public int compare(Products ob1, Products ob2) {
                    if (ob1.getCode().equals(ob2.getCode())) {
                        if (ob1.getQuantity()<ob2.getQuantity()){
                            return -1;
                        } else if (ob1.getQuantity()<ob2.getQuantity()){
                            return 1;
                        } else {
                            return 0;
                        }
                    }
                    return 0;
                }
            }

然后您可以删除重复项:

String prevCode = "";
for (int i = mProductsToBeSent.size(); --i >= 0) {
    Products prod = mProductsToBeSent.get(i);
    if (prod.getCode().equals(prevCode)) {
        mProductsToBeSent.remove(i);
    } else {
        prevCode = prod.getCode();
    }
}

更新:

但是,如果按照产品代码对列表进行排序,则可以在添加数量时删除重复项:

private static final Comparator<Products> PRODUCTS_CODE_COMPARATOR = new Comparator<Products>() {
                    @Override
                    public int compare(Products ob1, Products ob2) {
                        return ob1.getCode().compareTo(ob2.getCode());
                    }
                };

添加Products对象:

int pos = Collections.binarySearch(mProductsToBeSent, obj, PRODUCTS_CODE_COMPARATOR);

if (pos >= 0) {
    // already in the list
    Products obj2 = mProductsToBeSent.get(pos);
    obj2.setQuantity(obj2.getQuantity() + obj.getQuantity());
} else {
    // not found: insert obj
    mProductsToBeSent.add(-pos-1, obj);
}