2012-06-11 7 views
12

Ich habe eine Liste von Elementen, und ich möchte eine Liste von Elementen finden, die die boolesche Eigenschaft x=true haben.Wie finde ich Elemente in einer Sammlung nach Eigenschaften?

Ich weiß, dass dies durch Iteration erreicht werden kann, aber ich suchte nach einer gemeinsamen Methode, um das in Commons-Bibliothek wie Apache Commons zu tun.

+0

property = Feldvariable? – dacwe

+0

@dacwe, ja, das habe ich gemeint, tut mir leid. –

+0

Wie verstehst du "generische Methode"? –

Antwort

11

Das Problem ist, dass Iteration in Java ist oft viel einfacher und sauberer. Vielleicht werden die Closures von Java 8 das beheben. ;)

Vergleichen Sie mit @ Spaeths Lösung.

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); 

Wie Sie es viel kürzer und prägnanter sehen können.

+3

Wenn Sie hart codierte Prädikate haben, dann ist das wahr. Aber wenn Sie die Logik erweitern und verschiedene Elemente für den logischen Ausdruck bereitstellen müssen, die am Ende den richtigen Datensatz sauberer machen, ist eine funktionale Idiom-API wie die vorgeschlagene Guava. –

+0

@Vash +1 Das ist wahr, aber relativ selten. BTW: Ich verwende Prädikate in einer Bibliothek, die ich geschrieben habe, also bin ich nicht gegen sie. –

21

Sie könnten die Apache Commons-Sammlung verwenden, die ein Prädikat dafür implementiert.

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

Probe:

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); 
    } 
} 

Ein paar Beispiel finden Sie hier: http://apachecommonstipsandtricks.blogspot.de/2009/01/examples-of-functors-transformers.html

Und wenn Sie brauchen etwas mehr generisch, wie Wert eines bestimmten Feldes zu inspizieren oder Eigentum Sie könnten etwas tun wie:

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; 
     } 
    } 

} 

, dass eine bestimmte Eigenschaft auf einen erwarteten Wert vergleichen könnte, und die Verwendung wäre so etwas wie:

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

Danke für das Prädikat :) –

+1

Dies sollte die gewählte Antwort sein. –

+1

Gibt CollectionsUtils.select eine brandneue Sammlung zurück oder enthält diese neue Sammlung Verweise auf die ursprüngliche Sammlung. Ich habe versucht, dies zu verwenden, indem ich mein eigenes Prädikat definiere, jedoch werden beide meine Sammlungen geändert. – Rohan

1

dies in Java zu erreichen, können Sie hashCode außer Kraft setzen und gleich Methoden -

zum Beispiel

@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; 
} 

In diesem Beispiel habe ich eventId Integer-Wert mached. Sie können Ihre Klasse und ihre Eigenschaft hier verwenden. Danach können Sie die Lists contains, indexOf, lastIndexOf und die Methode get verwenden, um das Element in der Liste zu finden. Siehe unten.

//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)); 
} 
Verwandte Themen