注意:在上面的示例中,我无法覆盖equals方法,因为它已经用于其他目的。
我有以下课程:
public class A{ }
和
public class B{
private A a;
//GET, SET
}
现在,我有以下控制器:
public class ControllerOfMine{
private List<B> bs;
public List<B> remove(List<A> as){
if(as.isEmpty()){ //1, Dumb if
return bs;
}
List<B> result = new ArrayList<B>();
for(B item : bs){
for(A aItem : as){
if(item.getA().equals(aItem)){
continue;
} else {
result.add(item);
continue;
}
}
}
return result;
}
}
现在,我的问题是如何避免对as.isEmpty()
进行愚蠢的检查。我认为我的算法不太好。
答案 0 :(得分:1)
您可以通过O(1)查找操作替换内部循环。 这些方面的东西:
public class ControllerOfMine{
private List<B> bs;
public List<B> remove(List<A> as){
if (as.isEmpty()) return bs;
HashSet<A> quickLookup = new HashSet<A>();
quickLookup.addAll(as);
List<B> result = new ArrayList<B>();
for (B b: bs) {
if (!quickLookup.contains(b.getA())) {
result.add(b);
}
}
return result;
}
}
方法开头的单行几乎没有成本,它是O(1)。转换为HashSet
为O(n),但所有后续contains
个查询均已摊销O(1)
。在某些情况下,可以运行得更快(迭代列表实际上非常快,在查找操作中HashSet
开始优于它们之前,它们必须具有一定的长度。)