比较不同类型的列表

时间:2014-12-24 19:07:21

标签: java collections

我有两个列表如下

List<MyObject1> list1
List<Long> list2

list2基本上是MyObject1的Id列表,它是对象

中的属性
Public Class MyObject1 implements Serializable{

    private Long myObjId;
     .....
      .....
      //other elements go here

   public Long getMyObjId() {
    return myObjId;
    }

    public void setMyObjId(Long myObjId) {
    this.myObjId = myObjId;
}

我想比较两个列表以检查list1中的所有对象是否包含在list2

一种方法是迭代list1,从中创建一个新的Id列表,然后在其上使用containsAll方法。

是否有更简单的方法可以达到相同的效果?

2 个答案:

答案 0 :(得分:1)

在Java 8中,您可以编写您所描述的内容:“一种方法是迭代list1,从中创建一个新的Id列表,然后在其上使用containsAll方法。”在一行中:

list1.stream().map(a -> a.getMyObjId()).collect(Collectors.toList()).containsAll(list2);

map通过调用a.getMyObjectId将每个MyObeject转换为id,collect创建一个列表 结果。

答案 1 :(得分:0)

至少有两种概念上不同的方法:

  • 可以在列表中收集ID,并处理结果列表
  • 可以随时进行检查

第一个可归结为

boolean allIdsContained(List<MyObject> myObjects, List<Long> validIds) {
    List<Long> ids = new ArrayList<Integer>();
    for (MyObject m : myObjects) ids.add(m.getID());
    return validIds.continsAll(ids);
}

第二个可以写成

boolean allIdsContained(List<MyObject> myObjects, List<Long> validIds) {
    for (MyObject m : myObjects) {
        if (!validIds.contains(m.getID()) {
            return false;
        }
    }
    return true;
}

请注意,方法签名在两种情况下都是相同的,因此您可以根据需要自由更改实现。特别是,如果validIds的列表很大,那么首先将其转换为Set可能更有效。 (contains上的List方法是O(n),而Set上的方法是O(1)。然后该方法可以实现为

boolean allIdsContained(List<MyObject> myObjects, List<Long> validIds) {
    Set<Long> set = new HashSet<Long>(validIds);
    for (MyObject m : myObjects) {
        if (!set.contains(m.getID()) {
            return false;
        }
    }
    return true;
}

在任何情况下,所有这些方法都可以用Java 8 Lambdas更简洁地编写,但我认为这应该是一个实现细节,并且应该隐藏在这样的辅助方法中,无论它是如何实现的。