2010-09-21 6 views
6

Gibt es ein Konstrukt, in Java, die so etwas wie dies funktioniert (hier in Python implementiert):Java oneliner für Listenbereinigung

[] = [item for item in oldList if item.getInt() > 5] 

Heute habe ich mit so etwas wie ich:

ItemType newList = new ArrayList(); 
for(ItemType item : oldList) { 
    if(item.getInt > 5) { 
    newList.add(item); 
    } 
} 

Und mir sieht der erste Weg etwas schlauer aus.

Antwort

5

Java 7 might oder might not Schließungen implementieren und somit Funktionalität wie dies unterstützen, aber es funktioniert noch nicht, so auf der Java VM Sie die Optionen, um es zu tun haben, in Groovy, Scala oder Clojure (mögliche andere auch), aber in Java kann man nur mit Helfern wie Guavas Collections2.filter() in die Nähe kommen.

JDK 7 Beispielcode:

findItemsLargerThan(List<Integer> l, int what){ 
    return filter(boolean(Integer x) { x > what }, l); 
} 
findItemsLargerThan(Arrays.asList(1,2,5,6,9), 5) 

Groovy Beispielcode:

Arrays.asList(1,2,5,6,9).findAll{ it > 5} 

Guava Beispielcode:

Collections2.filter(Arrays.asList(1, 2, 5, 6, 9), 
    new Predicate<Integer>(){ 
     @Override 
     public boolean apply(final Integer input){ 
      return input.intValue() > 5; 
     } 
    } 
); 

Scala Beispielcode (dank Bolo):

Array(1, 2, 5, 6, 9) filter (x => x > 5) 
+2

oder Java 8: http://blogs.oracle.com/mr/entry/rethinking_jdk7 – Thilo

+0

@Thilo argh, schlechte Nachrichten. thx für den Link –

+0

danke für die Information! – Graslandpinguin

0

Nein, diese Art von dynamischen Sprachkonstrukt ist :-) in Java noch nicht unterstützt Damit Sie Ihre Option 2

3

Sie können leben werfen Sie einen Blick auf lambdaj. Es gibt eine Auswahlmethode, die Sie mit einer Bedingung verwenden können.

+0

Wow, das ist auch sehr cool (+1) –

1

Nichts ist unmöglich (-:

import java.util.ArrayList; 
import java.util.Arrays; 
import java.util.List; 

public class ListCleaner { 

    public static void main(String[] args) { 

     final List<Integer> oldList = Arrays.asList(new Integer[] { 23, 4, 5, 
       657 }); 
     System.out.println(oldList); 

     List<Integer> newList = new ArrayList<Integer>() { 
      { 
       for (Integer element : oldList) { 
        if (element > 5) { 
         this.add(element); 
        } 
       } 
      } 

     }; 
     System.out.println(newList); 
    } 
} 

Die einzige Einschränkung ist, dass der oldList endgültig sein muss

1

Es kann in reinem Java getan werden, aber Sie müssen eine Unterstützung Klasse Filter schreiben. für den folgenden Code erfolgreich auszuführen:

List<Integer> oldList = Arrays.asList(new Integer[] { 1, 2, 5, 6, 9 }); 
    List<Integer> newList = new Filter<Integer>(oldList) { 
     { 
      findAll(it > 5); 
     } 
    }.values(); 
    System.out.println(newList); // [6, 9] 

Falls Sie sich fragen, warum stellt dieser Code einen Blick auf Hidden features of Java nehmen. Doppel Klammer Initialisierung Dies schafft ein n anonyme Instanz der Klasse Filter, der die it-Variable enthält und die Methode findAll() bereitstellt.

Die Filterklasse selbst hat den einen Nachteil, dass eine neue Instanz für jedes Listenelement erstellt wird, um die Booleschen Bedingung bei findAll() zu bewerten:

public abstract class Filter<T> { 

    protected List<T> values = new ArrayList<T>(); 

    protected T it; 

    public Filter(List<T> values) { 
     if (values != null) { 
      this.values.addAll(values); 
     } 
     if (values.isEmpty()) { 
      throw new RuntimeException("Not for empty collections!"); 
     } 
     it = values.iterator().next(); 
     // instance initializer gets executed here, calls findAll 
    } 

    protected void findAll(boolean b) throws Throwable { 
     // exit condition for future calls 
     if (values.size() > 1) { 
      // only repeat for each entry, if values has multiple entries 
      Iterator<T> iterator = values.iterator(); 
      while (iterator.hasNext()) { 
       // don't evalute again for the first entry 
       if (!b) { 
        iterator.next(); 
        iterator.remove(); 
        b = true; 
       } else { 
        // for each other entry create an argument with one element 
        List<T> next = new ArrayList<T>(); 
        next.add(iterator.next()); 
        // get constructor of anonymous class 
        Constructor<?> constructor = this.getClass().getDeclaredConstructors()[0]; 
        // invoke constructor and thus execute instance initializer again 
        Filter<T> filtered = (Filter<T>) constructor.newInstance(new Object[] { null, next }); 
        // if values is empty, the condition didn't match and the element can be removed 
        if (filtered.values.isEmpty()) { 
         iterator.remove(); 
        } 
       } 
      } 
     } else { 
      // one element can be checked directly 
      if (!b) { 
       values.clear(); 
      } 
     } 
    } 

    public List<T> values() { 
     return values; 
    } 

} 

Aber als Beispiel Schöpfung ist ziemlich billig in diesen Tagen und die Die Filterklasse kann für alle Objekte verwendet werden. Es lohnt sich, sie in Ihr Utils-Paket aufzunehmen.

Greetz, ghad