在Java上的Vector中搜索属性

时间:2009-06-28 20:44:21

标签: java search vector iterator

我有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是否有类似变量名称(哎哟!)

5 个答案:

答案 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++)。)

现在,这里的棘手问题是,如果您在搜索时需要搜索的内容在运行时通过任意字符串确定。如果是这种情况,我可以建议两种选择:

  1. 根本不要将这些值存储为对象字段 - return iplane.pilotName。只需plane.destination(或更好,Map<String, String>其中Map<Field, String>是所有有效字段的Field,称为Enum
  2. 将它们存储为对象字段,但是如上所述,将字段名称中的地图预填充到plane.metadata个实例。
  3. 例如:

    PlaneMatcher

    哦,你可能会想要反思。别。 :)

答案 4 :(得分:-1)

一种简单的方法是将比较函数传递给搜索例程。或者,如果您需要更快的速度,请使用泛型。