mehta
mehta

Reputation: 755

Comparing lists of different types

I have two lists as follows

List<MyObject1> list1
List<Long> list2

The list2 is basically the list of Id's of MyObject1 which is a property in the object

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;
}

I want to compare the two lists to check if all the objects in list1 are contained in list2

One way is to iterate over the list1, create a new list of Id's out of it and then use the containsAll method on it.

Is there a simpler way to achieve the same result?

Upvotes: 0

Views: 342

Answers (2)

Marco13
Marco13

Reputation: 54611

There are at least two conceptually different approaches:

  • One could collect the IDs in a list, and work on the resulting list
  • One could do the check on-the-fly

The first one would boil down to something like

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);
}

The second one could be written as

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

Note that the method signature is the same in both cases, so you are free to change the implementation according to your needs. Particularly, if the list if validIds is large, then it could be more efficient to first convert it to a Set. (The contains method on a List is O(n), whereas on a Set, it is O(1)). Then the method could be implemented as

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;
}

In any case, all these methods could be written more concisely with Java 8 Lambdas, but I think that this should be an implementation detail, and should be hidden in such a helper method regardless of how it is implemented.

Upvotes: 0

Wickoo
Wickoo

Reputation: 7345

In Java 8 you can write what you described: "One way is to iterate over the list1, create a new list of Id's out of it and then use the containsAll method on it." in one line as:

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

map converts a each MyObeject to an id by calling a.getMyObjectId and collect creates a list as a result.

Upvotes: 1

Related Questions