如何比较两个对象列表之间的字段?

时间:2015-09-21 15:16:04

标签: java list collections

假设我有一个看起来像这样的对象:

public class Supermarket {

    public String supermarketId;
    public String lastItemBoughtId;

    // ...
}

我有两个超市列表,一个是" old",另一个" new" (即一个是本地的,另一个是从云中检索的。)

List<Supermarket> local = getFromLocal();
List<Supermarket> cloud = getFromCloud();

我想找到所有Supermarket个对象(给定supermarketIdlastItemBoughtId彼此不同的对象。

我想到的第一个解决方案是迭代第一个List,然后在第一个迭代内迭代第二个迭代,每次local.get(i).supermarketId.equals(cloud.get(j).supermarketId),检查lastItemBoughtId是否i {1}}元素与j元素的ID不同。如果它不同,我会将整个Supermarket对象添加到新列表中。

更清楚,像这样:

List<Supermarket> difference = new ArrayList<>();
for (Supermarket localSupermarket : local) {
    for (Supermarket cloudSupermarket : cloud) {
        if (localSupermarket.supermarketId.equals(cloudSupermarket.supermarketId) &&
        !localSupermarket.lastItemBoughtId.equals(cloudSupermarket.lastItemBoughtId))
            difference.add(cloudSupermarket);
    }
}

显然,这看起来非常效率低下。有没有更好的方法来处理这种情况?

2 个答案:

答案 0 :(得分:5)

一个解决方案:

  1. 通过列表运行一次,使用supermarketId作为关键字构建本地超市的地图
  2. 循环浏览云列表并进行比较,从地图中查找当地超市。
  3. 即。 O(n)代替O(n 2

    这是一个双线解决方案:

    Map<String, Supermarket> map = getFromLocal().stream()
        .collect(Collectors.toMap(s -> s.supermarketId, s -> s));
    List<Supermarket> hasDiffLastItem = getFromCloud().stream()
        .filter(s -> !map.get(s.supermarketId).lastItemBoughtId.equals(s.lastItemBoughtId))
        .collect(Collectors.toList());
    

答案 1 :(得分:1)

我会将其中一个列表放在Map中,并将Supermarket ID作为关键字,超市实例然后迭代另一个列表,从地图开始并比较lastItemBoughtId