如何搜索arraylist中的重复对象(由一个字段确定)并合并它们

时间:2013-12-04 10:52:55

标签: java arraylist

我有一个叫做PriceList的课程

class PriceList {
    Integer priceListID;
    ...
}

我已将其扩展到另一个类中以适应某些用户功能

class PriceListManager extends PriceList{
    boolean user;
    boolean manager;
}

一个用户可以拥有PriceListManager对象的ArrayList,它可以包含重复项(相同的PriceListID),所以我想找到这些重复项并比较它们的字段来创建一个条目 例如:

{ PriceListID = 5; user = false; manager = true; 
   PriceListID = 5; user = true; manager = false; }

应该成为

PriceListID = 5; user = true; manager = true;

最好的方法是什么? 我已经有两个类的equals方法,PriceList通过检查它们的ID来比较两个对象,而PriceListManagers这样做并检查两个布尔字段是否相同。

编辑:我需要查找具有相同ID的任何对象,因此我可以合并其属性并只留下一个对象。

5 个答案:

答案 0 :(得分:2)

这样的事情怎么样:

    Map<Integer, PriceListManager> map = new HashMap<Integer, PriceListManager>();

    for (PriceListManager manager : yourArrayList) {

        if (!map.contains(manager.getPriceListID())) {
            map.put(manager.getPriceListID(), manager);
        }

        if (manager.isUser()) {
            map.get(manager.getPriceListID()).setIsUser(true);
        }

        if (manager.isManager()) {
            map.get(manager.getPriceListID()).setIsManager(true);
        }
    }

    List<PriceListManager> newList = new ArrayList<PriceListManager>();
    newList.addAll(map.values());

    // Do stuff with newList....

答案 1 :(得分:1)

您可以尝试遍历列表并将其转换为HashMap,其中priceListID为key,PriceListManager为value。在迭代ArrayList时,检查hashmap是否存在特定priceListID的值:
1.如果是,则与当前的相比较 2.如果不等于根据您的逻辑更新。
3.如果相等则无需更新和
4.如果不存在则将其添加到hashmap中
我希望这会有所帮助。

答案 2 :(得分:1)

你已经在PriceListManager上实现了equals和hashCode来使用所有字段,但是出于这个特殊目的,你需要它们单独匹配priceListID,对吗?也许你想再给这个结构一个想法:你的实体在这里是什么? priceListID单独确定priceListManager?在任何情况下,如果你想要一个本地解决方案,我会使用Map然后做这样的事情:

Map<Integer, PriceListManager> lookup = new HashMap<Integer, PriceListManager>();
for (PriceListManager item: priceListManagers) {
  PriceListManager manager = lookup.get(item.getPriceListID());
  if (manager == null) {
    manager = new PriceListManager();
    manager.setPriceListID(item.getPriceListID());
    manager.setUser(false);
    manager.setManager(false);
    lookup.put(manager.getPriceListID(), manager);
  }
  manager.setUser(manager.getUser() || item.getUser());
  manager.setManager(manager.getManager() || item.getManager());
}

答案 3 :(得分:0)

如果您不想要重复。使用Set而不是ArrayList不是一个好主意吗? Set中保证唯一性。

您获得了性能并且必须实现更少的代码,因为您之后不必进行重复检查...

答案 4 :(得分:0)

浏览原始列表,如果找到已存在的对象,则将这两者合并为一个:

Collection<? extends PriceList> convertToMergedList(Iterable<? extends PriceList> listWithDuplicated) {
    Map<Integer, PriceList> idToMergedObject = new LinkedHashMap<>();
    for(PriceList price : listWithDuplicated) {
        if (idToMergedObject.get(price.piceListId) == null) {
            idToMergedObject.put(price.piceListId, price);
        } else {
            PriceList priceSoFar = idToMergedObject.get(price.piceListId);
            PriceList priceMerged = merge(priceSoFar, price);
            idToMergedObject.put(price.piceListId, priceMerged);
        }
    }

    return idToMergedObject.values();
}

PriceList merge(PriceList price1, PriceList price2) {
   // merging logic
}

我使用LinkedHashMap,以便保留元素的原始顺序。