根据其他列表中的Id匹配从列表中删除对象

时间:2014-04-04 14:18:32

标签: java algorithm collections arraylist

我有一个对象列表List<A> list1 ... A有两个成员idname ...现在我还有一个列表List<Integer> list2只包含了ID。 ..我需要从A中{id}不存在的list1中移除所有list2个对象。

到目前为止我尝试过:

void removeUnwanted(List<A> a, List<Integer> b) {
    for (A object : a) {
        if (!(b.contains(object.id))) {
            b.remove(object)
        }
    }
}

任何人都可以帮我提出最有效的方法吗?

4 个答案:

答案 0 :(得分:6)

你应该将id添加到一个集合中以进行快速搜索,然后遍历列表并删除不在id集合中的id:

Set<Integer> ids = new HashSet<Integer>(list2);
Iterator<A> it = list1.iterator();
while (it.hasNext()) {
    if (!ids.contains(it.next().id)) {
        it.remove();
    }
}

答案 1 :(得分:1)

可以在O(n)时间(平均大小写)和空格中通过创建HashMap<Integer,A>来完成,其中键是ID,值是A对象。

现在,迭代列表list2并仅生成具有与A中某个ID匹配的键的值(list2个对象)。

类似java的伪代码:

Map<Integer,A> map = new HashMap<>();
for (A a : list1) map.put(a.id,a);
for (int id : list2) { 
   A a = map.get(id);
   //do something with a, maybe populate a new list
}

另一种方法是对两个列表进行排序,并且并行迭代,同时丢弃没有匹配id的元素。这给出了O(nlogn)时间(最坏情况)和O(1)空间:

高级伪代码:

sort(list1) //according to id
sort(list2)
iter1 = 0
iter2 = 0
while (iter1<list1.size() && iter2<list2.size()) { 
   int id = list1.get(iter1).id
   if (id < list2.get(iter2)) { //discard and advance the smaller one
       list1.remove(iter1) //can be done efficiently if the list is linked list

   } else if (id == list2.get(iter2)) { //advance both, element should remain in list1
      iter1++; iter2++;
   } else { //advance iter2
      iter2++;
   }
}

答案 2 :(得分:1)

使用流(Java8)可以写:

List<Obj>     objects = new LinkedList<>();
List<Integer> ids     = new LinkedList<>();

// fill objects and ids

Set<Integer>  idHash  = new HashSet<>(ids);

objects = new LinkedList<>(objects.stream()
                                      .filter(e -> idHash.contains(e.getID()))
                                      .collect(Collectors.toList()));

答案 3 :(得分:0)

public void removeUnwanted(List<A> a, List<Integer> b) {
    boolean result = false;
    for (A object : a) {
        for (int i : b) {
            if ((i == (object.id))) {
                result = true;
            }
        }
        if (result == false) {
            a.remove(object);
        }
        result = false;
    }
}