2016-07-04 9 views
5

Я хочу удалить дублируемую запись на основе productId и priceTagId. Если удалить дубликаты, нам нужно добавить ВеличинуКак удалить дубликаты записей ArrayList в java

здесь в списке Детали изделия же PRODUCTID есть, но количество отличается, если мне нужно добавить количество в один

"productDetails" : [ 
     { 
      "productId" : "5764dfb7d991390e25edff74", 
      "quantity" : 2, 
      "netQty" : "10mg", 
      "priceTagId" : 1, 
      "alertAvailablity" : "Success" 
     }, 
     { 
      "productId" : "5764dfb7d991390e25edff74", 
      "quantity" : 4, 
      "netQty" : "10mg", 
      "priceTagId" : 1, 
      "alertAvailablity" : "Success" 
     }, 
     { 
      "productId" : "5764dfb7d991390e25edff74", 
      "quantity" : 6, 
      "netQty" : "30mg", 
      "priceTagId" : 3, 
      "alertAvailablity" : "Success" 
     }, 
     { 
      "productId" : "5764dfb7d991390e25edff74", 
      "quantity" : 8, 
      "netQty" : "30mg", 
      "priceTagId" : 3, 
      "alertAvailablity" : "Success" 
     }, 
     { 
      "productId" : "2345dfb7d991390e25edf659", 
      "quantity" : 8, 
      "netQty" : "30mg", 
      "priceTagId" : 3, 
      "alertAvailablity" : "Success" 
     } 
    ], 

я получил окончательный вывод как

"productDetails" : [ 
     { 
      "productId" : "5764dfb7d991390e25edff74", 
      "quantity" : 6, 
      "netQty" : "10mg", 
      "priceTagId" : 1, 
      "alertAvailablity" : "Success" 
     }, 
     { 
      "productId" : "5764dfb7d991390e25edff74", 
      "quantity" : 14, 
      "netQty" : "30mg", 
      "priceTagId" : 3, 
      "alertAvailablity" : "Success" 
     }, 
     { 
      "productId" : "2345dfb7d991390e25edf659", 
      "quantity" : 8, 
      "netQty" : "30mg", 
      "priceTagId" : 3, 
      "alertAvailablity" : "Success" 
     } 

    ], 

Основываясь на ProductID и priceTagId мне нужно, чтобы удалить дубликаты и добавить количество из удаленного дублей записи

private List<ProductDetail> removeDuplicateProducts(List<ProductDetail> productDetails) throws BaseException { 
    for (ProductDetail eachProductDetail : productDetails) { 
     for (ProductDetail eachInnerProductDetail : productDetails) { 
      if(eachProductDetail.getProductId().equals(eachInnerProductDetail.getProductId())) 
      { 
       if(eachProductDetail.getPriceTagId().equals(eachInnerProductDetail.getPriceTagId())) 
       { 
        eachProductDetail.setQuantity(eachProductDetail.getQuantity()+eachInnerProductDetail.getQuantity()); 
        productDetails.clear(); 
       } 
      } 

     } 
    }   
    return productDetails; 
} 

Но я понимаю, что это так? Что не так?

+1

Почему бы не поставить их в комплекте? –

+0

Используйте набор, если вы не хотите дублировать –

+0

Лучше пойти на набор, чтобы избежать дублирования записей.! –

ответ

1

Я хотел бы создать класс ProductKey:

class ProductKey { 
    private final Integer productId; 
    private final Integer priceTagId; 
    //constructor, getters, equals, hashcode 
} 

Затем положить все продукты в Map<ProductKey, List<ProductDetail>>, где ключ является экземпляром класса выше и значением является список всех продуктов, которые соответствуют ProductKey.

Затем объединить элементы каждого списка путем суммирования величин и т.д.

Вы можете также, вероятно, запустить эти два шага за один раз.

0

Вы можете использовать набор для удаления дубликатов и изменить количество в равных метод класса ProductDetail

import java.util.ArrayList; 
import java.util.LinkedHashSet; 
import java.util.List; 
import java.util.Set; 

public class Test { 
public static void main(String[] args) { 
    List<ProductDetail> productDetails = new ArrayList<ProductDetail>(); 
    ProductDetail p1 = new ProductDetail("1", "pt1", 10); 
    ProductDetail p2 = new ProductDetail("1", "pt1", 40); 
    ProductDetail p3 = new ProductDetail("2", "pt1", 30); 

    productDetails.add(p1); 
    productDetails.add(p2); 
    productDetails.add(p3); 

    List<ProductDetail> list = removeDuplicateProducts(productDetails); 
    for (ProductDetail p : list) { 
     System.out.println(p); 
    } 

} 

private static List<ProductDetail> removeDuplicateProducts(
     List<ProductDetail> productDetails) { 

    Set<ProductDetail> set = new LinkedHashSet<ProductDetail>(
      productDetails); 

    List<ProductDetail> list = new ArrayList<ProductDetail>(); 
    list.addAll(set); 

    return list; 
} 

private static class ProductDetail { 
    public ProductDetail(String productId, String priceTagId, int quantity) { 
     this.productId = productId; 
     this.priceTagId = priceTagId; 
     this.quantity = quantity; 
    } 

    String productId; 
    String priceTagId; 
    int quantity; 

    public String getProductId() { 
     return productId; 
    } 

    public void setProductId(String productId) { 
     this.productId = productId; 
    } 

    public String getPriceTagId() { 
     return priceTagId; 
    } 

    public void setPriceTagId(String priceTagId) { 
     this.priceTagId = priceTagId; 
    } 

    public int getQuantity() { 
     return quantity; 
    } 

    public void setQuantity(int quantity) { 
     this.quantity = quantity; 
    } 

    @Override 
    public String toString() { 
     return (this.productId+"--"+this.priceTagId+"--"+this.quantity); 

    } 

    @Override 
    public int hashCode() { 
     return (this.priceTagId.hashCode()*this.priceTagId.hashCode()); 
    } 

    @Override 
    public boolean equals(Object obj) { 
     ProductDetail p1 = (ProductDetail) obj; 
     if ((p1.getPriceTagId().equals(this.getPriceTagId()) && p1 
       .getProductId().equals(this.getProductId()))) { 
      p1.setQuantity(this.getQuantity() + p1.getQuantity()); 
      return true; 
     } 
     return false; 
    } 
} 

}

+0

Можете ли вы поделиться им с помощью foreach? –

+0

Отредактировано ответ –

+0

вы первый ответ, я могу понять, но этот не правильный –

3

Наиболее эффективным решением является использование карты, где ключ представляет собой сочетание всех поля, которые вы считаете, чтобы сделать продукты одинаковыми, а значение содержит любую дополнительную информацию.

В вашем случае вы можете сделать

private Collection<ProductDetail> accumulateDuplicateProducts(List<ProductDetail> productDetails) { 
    // use a map to quickly find entries which match. 
    // using a linked HashMap means the order of addition is preserved. 
    Map<String, ProductDetail> productMap = new LinkedHashMap<>(); 
    for (ProductDetail pd : productDetails) { 
     // build a composite key of the fields you want to match on. 
     String key = pd.getProductId() + " " + pd.getPriceTag(); 
     // if the Strings match they should be merged. 
     // if there was no previous entry, use the current one. 
     // if there was a previous entry call merge() to combine them. 
     productMap.compute(key, (k, pd2) -> pd2 == null ? pd : merge(pd, pd2)); 
    } 
    return productMap.values(); 
} 

private static ProductDetail merge(ProductDetail pd, ProductDetail pd2) { 
    // combine two ProductDetails 
} 

Примечания: время сложность O(n) вместо O(n^2), если вы используете два вложенных цикл.

Но я понимаю, что это так? Что не так?

Одна из проблем, у вас есть

productDetails.clear(); 

другая проблема, у вас есть то, что вы сравните каждую запись от каждой записи, например, что у вас есть две записи A и B, которые соответствуют

A is compared with A so A *= 2 
A is compared with B do A += B 
B is compared with A so B += A 
B is compared with B so B *= 2 

Вы все еще в конечном итоге с двумя входами, так как вы не вынимая один.

+0

Я не мог получить его. Можете ли вы уточнить свой код, если у вас есть время? –

+0

На самом деле мой мотив: я делаю один торговый сайт, когда пользователь добавляет тот же товар в корзину в корзину Мне нужно только обновить количество –

+0

@AraviS Я обновил свой ответ с комментариями. Накопление количества для одного и того же продукта является довольно распространенным. В торговле у вас могут быть отрицательные количества;) –

0

В этом примере я бы использовал карту. Давайте посмотрим, почему:

private List<ProductDetail> removeDuplicateProducts(List<ProductDetail> productDetails) throws BaseException { 

Та же подпись метода будет в порядке.Теперь разница

//This map will contain the final set of elements 
Map<Integer, ProductDetail> map = new HashMap<Integer, ProductDetail>(); 

for (ProductDetail item: productDetails){ 
    //If map already contains the same productId it adds the quantities but doesn't add the same productId again 
    if(map.containsKey(item.getProductId())){ 
     ProductDetail mapItem = map.get(item.getProductId()); 
     mapItem.setQuantity(mapItem.getQuantity() + item.getQuantity()); 
    } 
    //If map doesn't contain the same productId, it's added for the first time 
    else{ 
     mapItem.put(item.getProductId(), item); 
    } 
} 

//At this point the map only contains a set of different productId. Now it will be dumped into a list and returned. 
return new ArrayList<String>(map.values()); 

Я надеюсь, что это помогает

0

В вашем коде, если вы используете «для каждого» заявления, как это, элемент списка всегда имеет один раз, что он по сравнению с самими собой и это даст неправильный результат. Вы должны использовать индекс для доступа к элементам списка

for (int i = 0; i <= list.size() - 1; i++) { 
for (int j = i + 1; j <= list.size() - 1; j++) { 
    <enter your if statements here> 
} 
} 

и rememeber удалить дубликат элемента с помощью list.remove (indexOfTheDuplicate), list.clear() удаляет все элементы списка.

0

Вы можете изменить подход, чтобы вернуть новый список с необходимыми данными.

private List<ProductDetail> removeDuplicateProducts(List<ProductDetail> productDetails) { 

    List<ProductDetail> returnList = new ArrayList<ProductDetail>(); 
    boolean exists = false; 

    for (ProductDetail eachProductDetail : productDetails) { 
     exists = false; 
     for (ProductDetail eachInnerProductDetail : returnList) { 
      // Your match condition 
      if (eachProductDetail.getProductId().equals(eachInnerProductDetail.getProductId()) 
       && eachProductDetail.getPriceTagId().equals(eachInnerProductDetail.getPriceTagId())) { 
       exists = true; 
       eachInnerProductDetail.setQuantity(eachProductDetail.getQuantity() + eachInnerProductDetail.getQuantity()); 
       break; 
      } 
     } 

     // add to output list if not exists 
     if (!exists){ 
      returnList.add(eachProductDetail); 
     } 

    } 
    return returnList; 
} 

Таким образом, вы можете иметь исходный список и новый.

Смежные вопросы