从ArrayList获取匹配子集

时间:2011-10-20 05:21:59

标签: java iterator

我有一些ArrayList POJO。让我们说员工。

然后我得到另一个ArrayList,它只包含POJO的'id'。(即员工)

现在,我想从主列表中找到匹配ID的子列表。

我可以通过迭代主列表并将其与另一个列表的每个id进行比较来实现。

但是,我想找出其他最佳解决方案。

任何指针都会受到赞赏。

4 个答案:

答案 0 :(得分:5)

修改

  • 对Employee的ArrayList(或副本)进行排序。运行时间为O(n*log n)
  • 查找特定ID的第一个和最后一个索引。这需要O(n)运行时间
  • 使用开始和结束索引提取子列表。这也需要O(n)

总运行时间:O(n * log n)

以下是整个程序:

初始化Employee ArrayList:

ArrayList<Employee> empArray = new ArrayList<Employee>();

创建一些随机的员工进行测试:

Employee empTemp = new Employee();
empTemp.setId("1");
empTemp.setName("emp1");
empArray.add(empTemp);

empTemp = new Employee();
empTemp.setId("2");
empTemp.setName("emp2");
empArray.add(empTemp);

empTemp = new Employee();
empTemp.setId("1");
empTemp.setName("emp3");
empArray.add(empTemp);

empTemp = new Employee();
empTemp.setId("4");
empTemp.setName("emp4");
empArray.add(empTemp);

empTemp = new Employee();
empTemp.setId("2");
empTemp.setName("emp5");
empArray.add(empTemp);

将Employees ArrayList w.r.t排序为他们的ID。

Collections.sort(empArray, new Comparator<Object>() {

    public int compare(Object obj0, Object obj1) {
        // TODO Auto-generated method stub
        Employee one = (Employee) obj0; 
        Employee two = (Employee) obj1;
        return one.getId().compareTo(two.getId());
    }
});

初始化String的临时ArrayList,其中只包含Employees的ID:

ArrayList<String> idOnly = new ArrayList<String>();
idOnly.add("1");
idOnly.add("3");

在这里,我们创建一个新的Employee对象,并为其分配我们想要创建子列表的id:

empTemp = new Employee();
empTemp.setId(idOnly.get(1));

查找该ID的开始和结束索引:

int start = empArray.indexOf(empTemp);
int end = empArray.lastIndexOf(empTemp);

从开始和结束索引创建子列表:

List<Employee> temp = null;
if (start != -1 && end != -1){
    temp = empArray.subList(start, end+1);
}

只需在员工类中调整Override equals(Object obj)

@Override
public boolean equals(Object obj) {
    // TODO Auto-generated method stub
    Employee two = (Employee) obj; 
    return this.id.equals(two.getId());
}

我知道它有点棘手,但需要n*log(n)运行时间。

答案 1 :(得分:1)

将ID放入Set中。然后,您可以遍历您的Employees列表,并测试它是否在您正在寻找的集合中,而没有错误的O(n^2)运行时间。

如果你想制作更漂亮的代码,你也可以查看Maps.uniqueIndex来建立一个你可以从中取出的地图。

答案 2 :(得分:1)

无论如何,我必须迭代收集。最佳解决方案是使用一些可以为您执行此操作的库。番石榴有Predicate在这种情况下真的很有帮助。检查示例:

//First we build a map that stores Id => Pojo pairs
Map<Integer, POJO> map = Maps.uniqueIndex(yourPojoList, new Function<POJO, Integer>() {
  public Integer apply(POJO pojo) {
    return pojo.getId();
}});
//Now we just intersect both set and your id's list
matchingIds = map.keySet().retainAll(new HashSet(youIdCollection)); //matchingIds is what you need

答案 3 :(得分:0)

id字段的类型是什么?一种方法可能是将POJO插入到数组中某个点的第一个ArrayList中,其中point等于employee的id(仅当它是一个整数时才有效)。

当然这意味着您可以修改第一个ArrayList的插入。否则循环遍历数组是我意识到解决该问题的唯一方法。