我有两个列表如下
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方法。
是否有更简单的方法可以达到相同的效果?
答案 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)
至少有两种概念上不同的方法:
第一个可归结为
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更简洁地编写,但我认为这应该是一个实现细节,并且应该隐藏在这样的辅助方法中,无论它是如何实现的。