我在Java中有一个对象的ArrayList。这些对象有四个字段,其中两个字段用于判断该对象是否等同于另一个对象。鉴于这两个字段,我正在寻找最有效的方法来确定该数组是否包含该对象。
问题在于这些类是根据XSD对象生成的,因此我无法修改类本身以覆盖.equals方法。
除了循环遍历并手动比较每个对象的这两个字段,然后在找到时跳出外,是否有更好的方法?这种方法看起来很混乱,我正在寻找更好的方法。
编辑:ArrayList来自未组合为对象的SOAP响应。
我在Java中有一个对象的ArrayList。这些对象有四个字段,其中两个字段用于判断该对象是否等同于另一个对象。鉴于这两个字段,我正在寻找最有效的方法来确定该数组是否包含该对象。
问题在于这些类是根据XSD对象生成的,因此我无法修改类本身以覆盖.equals方法。
除了循环遍历并手动比较每个对象的这两个字段,然后在找到时跳出外,是否有更好的方法?这种方法看起来很混乱,我正在寻找更好的方法。
编辑:ArrayList来自未组合为对象的SOAP响应。
这取决于你需要多么高效。简单地迭代列表寻找满足某个条件的元素是O(n)的,但如果你能实现Equals方法,ArrayList.Contains也是O(n)的。如果你不是在循环或内部循环中进行这个过程,这种方法可能就可以了。
如果你真的需要非常高效的查找速度,需要做两件事:
当然,构建此HashSet仍然具有O(n)成本。只有当构建HashSet的成本与你需要执行的所有contains()检查的总成本相比可以忽略时,你才会获得任何收益。尝试构建一个没有重复项的列表就是这样一种情况。
你可以使用Java内置的排序和二分查找方法中的Comparator。假设你有一个像这样的类,其中a和b是你想用来进行排序的字段:
class Thing { String a, b, c, d; }
您需要定义自己的比较器(Comparator):
Comparator<Thing> comparator = new Comparator<Thing>() {
public int compare(Thing o1, Thing o2) {
if (o1.a.equals(o2.a)) {
return o1.b.compareTo(o2.b);
}
return o1.a.compareTo(o2.a);
}
};
然后对您的列表进行排序:
Collections.sort(list, comparator);
最后进行二分查找:
int i = Collections.binarySearch(list, thingToFind, comparator);
考虑到你的限制,你只能使用暴力搜索(或创建索引,如果搜索将会重复)。你能否详细说明一下如何生成 ArrayList
-- 也许在那里有一些空间。
如果你只是想要更漂亮的代码,请考虑使用Apache Commons Collections类,尤其是CollectionUtils.find(),这是现成的语法糖:
ArrayList haystack = // ...
final Object needleField1 = // ...
final Object needleField2 = // ...
Object found = CollectionUtils.find(haystack, new Predicate() {
public boolean evaluate(Object input) {
return needleField1.equals(input.field1) &&
needleField2.equals(input.field2);
}
});
Detect
查询来完成此操作。Foo foo = ...
Detect<Foo> query = Detect.from(list);
for (Detect<Foo> each: query)
each.yield = each.element.a == foo.a && each.element.b == foo.b;
return query.result();
List list = new ArrayList();
fillFromSoap( list );
List list = new MyCustomSpecialList();
fillFromSoap( list );
class MyCustomSpecialList extends AbstractList {
private Map<Integer, YourObject> internalMap;
public boolean add( YourObject o ) {
internalMap.put( o.getThatFieldYouKnow(), o );
}
public boolean contains( YourObject o ) {
return internalMap.containsKey( o.getThatFieldYouKnow() );
}
}
几乎就像一个HashSet,这里的问题是HashSet依赖于hashCode方法的良好实现,而您可能没有。相反,您使用“您知道的那个字段”作为哈希值,该字段使一个对象等于另一个对象。