2010-09-21 45 views
6

Có một cấu trúc trong java mà không một cái gì đó như thế này (ở đây thực hiện trong python):Java oneliner cho danh sách dọn dẹp

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

Hôm nay tôi đang sử dụng một cái gì đó như:

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

Và để tôi là cách đầu tiên thông minh hơn một chút.

Trả lời

5

Java 7 might hoặc might not thực hiện đóng cửa và do đó hỗ trợ chức năng như thế này, nhưng hiện tại nó không, vì vậy trên máy ảo Java bạn có các tùy chọn để làm điều đó trong Groovy, Scala hoặc Clojure (có thể những người khác, quá), nhưng trong java bạn chỉ có thể đạt được điều đó bằng cách sử dụng những người trợ giúp như số Collections2.filter() của Guava.

JDK mã 7 mẫu:

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

Groovy mẫu mã:

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

Ổi Sample Code:

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

Scala mẫu mã (nhờ Bolo):

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

Hoặc Java 8: http://blogs.oracle.com/mr/entry/rethinking_jdk7 – Thilo

+0

@Thilo argh, tin xấu. thx cho liên kết –

+0

cảm ơn thông tin! – Graslandpinguin

0

Không, loại ngôn ngữ xây dựng năng động không được hỗ trợ trong Java chưa :-) Vì vậy, bạn phải sống với lựa chọn của bạn 2

3

Bạn có thể xem lambdaj. Có một phương pháp chọn bạn có thể sử dụng với điều kiện hamcrest.

+0

Chà, điều đó cũng rất tuyệt vời +1) –

1

Không có gì là không thể (-:

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

Ràng buộc duy nhất là oldList phải là thức

1

Nó có thể được thực hiện trong tinh khiết Java, nhưng bạn cần phải viết một bộ lọc hỗ trợ lớp. cho đoạn mã sau để chạy thành công:

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] 

Trong trường hợp bạn tự hỏi tại sao mã này biên dịch hãy nhìn vào Hidden features of Java:. đúp khởi cú đúp này tạo ra một n thể hiện ẩn danh của lớp Bộ lọc có chứa biến đó và cung cấp phương thức findAll().

Lớp Lọc chính nó có một nhược điểm mà một trường hợp mới được tạo ra cho mỗi phần tử danh sách để đánh giá tình trạng boolean tại FindAll():

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

} 

Nhưng khi tạo dụ là khá rẻ những ngày này và Lớp lọc có thể sử dụng cho tất cả các đối tượng, nó có thể đáng giá bao gồm trong gói Utils của bạn.

Greetz, GHad

Các vấn đề liên quan