2009-06-28 70 views
2

我有一個Vector對象,並且必須在內部搜索這些對象的隨機屬性(例如,Plane類,Vector包含Plane;我必須搜索有時爲destination,其他爲pilotName)。在Java上搜索Vector中的屬性

我知道我可以遍歷Vector使用Iterator,但我一直在堅持如何更改字符串與對象上的屬性之間的比較。我想到使用switch,但另一種意見會很酷。


更新1:

我寫的代碼是這樣的(Java的n00b警惕!):

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是否有類似變量變量名稱(ouch!)

+3

你可以發佈你試過的代碼嗎? – Cogsy 2009-06-28 20:47:56

+0

我認爲這裏的關鍵詞是* random *屬性。我已經在下面發佈了一個答案,因爲我認爲你正在詢問如何實現一種算法,該算法在編碼算法的過程中搜索某些你不知道正在搜索的內容*。如果你不問這個問題,那麼我建議你改進你的問題,使其更清晰。 – 2009-06-28 21:26:27

回答

-1

一個簡單的方法是將比較函數傳遞給您的搜索例程。或者,如果您需要更多速度,請使用泛型。

+1

「如果您需要更多速度,請使用泛型」?你究竟在幹什麼? – 2009-06-28 21:11:51

+0

也許程序員可以輸入程序的速度? – 2009-06-28 21:45:56

2

使用Collections.binarySearch並提供Comparator

編輯:這假定Vector排序。否則,必須進行線性搜索。

+0

請注意,爲此,需要使用Compartor對Vector進行排序 – akf 2009-06-28 20:51:51

0

equals()方法是最好的選擇。對於這些迭代,你可以做這樣的事情:

for (Plane plane: planes) { 
    if ("JFK".equals(plane.getDestination())) { 
     // do your work in here; 
    } 
} 

,或者您可以覆蓋內Planeequals()方法,看看是否在傳遞的字符串您的目的地(或試點)相匹配。這將允許您使用Vector上的indexOf(Object)indexOf(Object, index)方法返回對象的索引(s)。一旦你有了,你可以使用Vector.get(index)爲你返回Object。

Plane.java

public boolean equals(Object o) { 
    return o.equals(getDestination()) || 
      o.equals(getPilot()) || 
      super.equals(o);  

} 

沒有要使用此選項完成更多的工作,因爲你需要重寫hashCode()以及(see documentation)。

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個向量:

List<Integer> is = ... 
findFirst(is, new Predicate<Integer> { 
    public boolean evaluate(Integer i) { return i % 2 == 0; } 
}); 

但是你可以實現你想要的任何方式的謂語;任何任意搜索

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費心 - 只需使用一個老式的for (int i = 0; i < planes.size(); i++)循環,當你有匹配時,return i。)

現在,棘手的一點是,如果你在搜索的時候真的被任意字符串在運行時識別出來。如果是這樣的話,我可以建議兩種選擇:

  1. 這些值不存儲爲對象字段 - plane.pilotNameplane.destination - 在所有。只需要有一個Map<String, String>(或更好的Map<Field, String>,其中Field是所有有效字段的Enum)稱爲類似plane.metadata
  2. 將它們存儲爲對象字段,但是如上所述預先填充字段名稱到PlaneMatcher實例的映射。

例如:

private static final Map<String, PlaneMatcher> MATCHERS = Collections.unmodifiableMap(new HashMap<String, PlaneMatcher>() {{ 
    put("pilotName", new PlaneMatcher() { 
     boolean matches(Plane plane, String query) { 
      return query.equals(plane.getPilotName()); 
     }); 
    ... 
    put("destination", new PlaneMatcher() { 
     boolean matches(Plane plane, String query) { 
      return query.equals(plane.getDestination()); 
     }); 
}} 

... 

public int search(String whatSearch, String query){ 
    PlaneMatcher matcher = MATCHERS.get(whatSearch); 
    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; 
} 

哦,你可能會使用反射。別。 :)