2012-06-11 63 views
12

我有一個項目列表,我想查找具有布爾屬性x=true的項目列表。如何通過屬性查找集合中的元素?

我知道這可以通過迭代來完成,但我正在尋找一種常見的方法來在Commons庫(如Apache Commons)中執行此操作。

+0

屬性=字段變量? – dacwe

+0

@dacwe,是的,這就是我的意思,對不起。 –

+0

你如何理解'通用方法「? –

回答

11

問題是,在Java中的迭代通常更簡單和更清潔。也許Java 8的關閉會解決這個問題。 ;)

與@ Spaeth的解決方案進行比較。

List<String> mixedup = Arrays.asList("A", "0", "B", "C", "1", "D", "F", "3"); 
List<String> numbersOnlyList = new ArrayList<>(); 
for (String s : mixedup) { 
    try { 
     // here you could evaluate you property or field 
     Integer.valueOf(s); 
     numbersOnlyList.add(s); 
    } catch (NumberFormatException ignored) { 
    } 
} 
System.out.println("Results of the iterated List: " + numbersOnlyList); 

正如你可以看到它更短,更簡潔。

+3

如果你有硬編碼謂詞,那麼是真的。但是當你需要擴展邏輯併爲邏輯表達式提供各種元素時,最終給出適當的數據集清理器就是一些功能性的成語API,就像Guava提出的那樣。 –

+0

@Vash +1這是事實,但相對罕見。順便說一句:我在我寫的庫中使用謂詞,所以我不反對它們。 –

21

你可以使用apache的commons集合實現Predicate。

http://commons.apache.org/collections/apidocs/org/apache/commons/collections/CollectionUtils.html

樣品:

package snippet; 

import java.util.Arrays; 
import java.util.Collection; 

import org.apache.commons.collections.CollectionUtils; 
import org.apache.commons.collections.Predicate; 

public class TestCollection { 

    public static class User { 

     private String name; 

     public User(String name) { 
      super(); 
      this.name = name; 
     } 

     public String getName() { 
      return name; 
     } 

     public void setName(String name) { 
      this.name = name; 
     } 

     @Override 
     public String toString() { 
      return "User [name=" + name + "]"; 
     } 

    } 

    public static void main(String[] args) { 
     Collection<User> users = Arrays.asList(new User("User Name 1"), new User("User Name 2"), new User("Another User")); 
     Predicate predicate = new Predicate() { 

      public boolean evaluate(Object object) { 
       return ((User) object).getName().startsWith("User"); 
      } 
     }; 
     Collection filtered = CollectionUtils.select(users, predicate); 
     System.out.println(filtered); 
    } 
} 

幾個樣品可以在這裏找到: http://apachecommonstipsandtricks.blogspot.de/2009/01/examples-of-functors-transformers.html

如果你需要更多的東西通用的,比如檢查特定的字段或屬性的值你可以這樣做:

public static class MyPredicate implements Predicate { 

    private Object expected; 
    private String propertyName; 

    public MyPredicate(String propertyName, Object expected) { 
     super(); 
     this.propertyName = propertyName; 
     this.expected = expected; 
    } 

    public boolean evaluate(Object object) { 
     try { 
      return expected.equals(PropertyUtils.getProperty(object, propertyName)); 
     } catch (Exception e) { 
      return false; 
     } 
    } 

} 

這可能一個特定的屬性比較的預期值,並利用會是這樣的:

Collection filtered = CollectionUtils.select(users, new MyPredicate("name", "User Name 2")); 
+0

感謝您的謂詞:) –

+1

這應該是選擇的答案。 –

+1

使用CollectionsUtils.select是否返回一個全新的集合,或者這個新集合是否包含對原始集合的引用。我試圖通過定義我自己的謂詞來使用它,但是我的兩個集合都被修改了。 – Rohan

1

要做到這一點在Java中,你可以重寫的hashCode和equals方法 -

例如

@Override 
public int hashCode() { 
    return eventId; 
} 

@Override 
public boolean equals(Object obj) { 
    if(obj instanceof CompanyTimelineView) { 
     CompanyTimelineView new_name = (CompanyTimelineView) obj; 
     if(new_name.eventId.intValue() == this.eventId.intValue()){ 
      return true; 
     } 
    } 
    return false; 
} 

在這個例子中,我有mached eventId整數值。你可以在這裏使用你的班級和他的財產。 之後,您可以使用列表的包含,indexOf,lastIndexOf和get方法來查找列表中的元素。見下文。

//tempObj is nothing but an empty object containing the essential properties 
//tempObj should posses all the properties that are being compared in equals method. 

if(listOfObj.contains(tempObj)){ 
    return listOfObj.get(listOfObj.indexOf(tempObj)); 
} 
相關問題