我有Vector
个对象,并且必须在里面搜索这些对象的随机属性(例如,Plane
类,Vector
包含Plane
我有时会搜索destination
,有些搜索到pilotName
。)
我知道我可以使用Vector
遍历Iterator
,但我一直坚持如何更改String与对象属性之间的比较。我想过使用switch
,但另一种观点会很酷。
更新1:
我写的代码是这样的(Java n00b alert!):
public int search(String whatSearch, String query){
int place = -1;
boolean found = false;
for ( Iterator<Plane> iteraPlane = this.planes.iterator(); iteraPlane.hasNext() && found == false; ) {
Plane temp = (Plane) iteraPlane.next();
/* Here is where I have to search for one of many attributes (delimited by whatSearch */
}
return place;
}
似乎我坚持线性搜索(这是我能够付出的代价)。无论如何,我在想Java是否有类似变量名称(哎哟!)
答案 0 :(得分:4)
我认为您的问题是您希望有一种方法可以根据集合类型的某些属性搜索结果。 Java在这方面很弱,因为它最好用具有闭包的语言表达。你需要的是:
public interface Predicate<T> {
public boolean evaluate(T t);
}
然后你的搜索方法如下:
public static <T> T findFirst(List<T> l, Predicate<T> p) { //use List, not Vector
for (T t : l) { if (p.evaluate(t)) return t; }
return null;
}
然后任何人都可以使用此通用搜索方法。例如,要在Integer
s:
List<Integer> is = ...
findFirst(is, new Predicate<Integer> {
public boolean evaluate(Integer i) { return i % 2 == 0; }
});
但是你可以以任何你想要的方式实现谓词;任意搜索
答案 1 :(得分:2)
使用Collections.binarySearch
并提供Comparator
。
编辑:这假定Vector
已排序。否则,必须进行线性搜索。
答案 2 :(得分:0)
equals()
方法是最佳选择。对于这些迭代,您可以执行以下操作:
for (Plane plane: planes) {
if ("JFK".equals(plane.getDestination())) {
// do your work in here;
}
}
或者您可以覆盖equals()
中的Plane
方法,以查看传入的字符串是否与您的目标(或导频)匹配。这将允许您使用Vector
上的indexOf(Object)
和indexOf(Object, index)
方法返回对象的索引。完成后,您可以使用Vector.get(index)
为您返回Object。
Plane.java
中的:
public boolean equals(Object o) {
return o.equals(getDestination()) ||
o.equals(getPilot()) ||
super.equals(o);
}
此选项还有很多工作要做,因为您还需要覆盖hashCode()
(see documentation)。
答案 3 :(得分:0)
请参阅上面的@oxbow_lakes - 我认为您想要的不是将String
作为whatSearch
传递,而是要传递一小段代码知道如何获取属性感兴趣的。对于较不通用的版本:
public static interface PlaneMatcher {
boolean matches(Plane plane, String query);
}
public int search(PlaneMatcher matcher, String query){
int place = -1;
boolean found = false;
for ( Iterator<Plane> iteraPlane = this.planes.iterator(); iteraPlane.hasNext() && found == false; ) {
Plane temp = (Plane) iteraPlane.next();
if (matcher.matches(temp, query) {
found = true;
}
place++;
}
return place;
}
...
// example
int pilotNameIndex = search(new PlaneMatcher() {
boolean matches(Plane plane, String query) {
// note: assumes query non-null; you probably want to check that earlier
return query.equals(plane.getPilotName());
}
}, "Orville Wright");
(顺便说一句,如果它是你感兴趣的索引而不是Plane
本身,我就不会打扰Iterator
- 只需使用一个老式{{1} }}循环,当你有匹配时,for (int i = 0; i < planes.size(); i++)
。)
现在,这里的棘手问题是,如果您在搜索时需要搜索的内容在运行时通过任意字符串确定。如果是这种情况,我可以建议两种选择:
return i
,plane.pilotName
。只需plane.destination
(或更好,Map<String, String>
其中Map<Field, String>
是所有有效字段的Field
,称为Enum
。plane.metadata
个实例。 例如:
PlaneMatcher
哦,你可能会想要反思。别。 :)
答案 4 :(得分:-1)
一种简单的方法是将比较函数传递给搜索例程。或者,如果您需要更快的速度,请使用泛型。