2010-05-06 47 views
6

The question but in C#. Vậy Java có lệnh C# không? Tôi cần nó cho Matches-SearchTerm-Files-relationship.Java: lặp qua danh sách các danh sách?

foreach(var i in BunchOfItems.SelectMany(k => k.Items)) {} 

[Tại sao không cho-vòng?] Tôi đã làm cấu trúc như vậy trong lồng nhau cho vòng nhưng họ sớm trở thành cồng kềnh. Vì vậy, tôi thích một cái gì đó succint hơn như trên.

public static Stack<Integer[]> getPrintPoss(String s,File f,Integer maxViewPerF) 
{ 
    Stack<File> possPrint = new Stack<File>(); 
    Integer[] poss = new Integer[4](); 
    int u,size; 
    for(File f:files) 
    { 
     size = f2S(f).length(); 
     u = Math.min(maxViewsPerF,size); 
     for(int i=0; i<u;i++) 
     { 
      // Do something --- bloated, and soon out of control 
      // wants more succintly 

     } 
    } 
    return possPrint; 
} 
+1

Thư viện này có triển khai selectMany() trông giống như thế này cho yêu cầu của bạn: cho (val i: BunchOfItems.selectMany (bunchItemSelector()) {}. Xem https://github.com/nicholas22/jpropel-light –

Trả lời

1

Có khoảng nửa kiên nhẫn cho đến khi năm JDK7 là cuối cùng sẽ bao gồm Closures. Điều này cung cấp cú pháp simliar và các khả năng tương tự như LINQ đã được thể hiện trong câu trả lời mà bạn đang nói đến.

6
for (List<Object> lo : list) { 
    for (Object o : lo) { 
     // etc etc 
    } 
} 

Tôi không nghĩ rằng có một giải pháp đơn giản hơn.

+0

OP yêu cầu một loại giải pháp LINQ mà C# cung cấp.Ông đã biết cách lặp qua Danh sách, anh ta muốn một giải pháp thanh lịch, thật không may, Java không có thứ gì tương đương với LINQ. –

1

Tôi có phiên bản của riêng mình. Chờ đợi một cách tuyệt vọng cho đóng cửa trong Java:

public static <T, E> Iterable<T> transformMany(Iterable<E> iterable, Func<E, Iterable<T>> f) { 
    if (null == iterable) 
     throw new IllegalArgumentException("null iterable"); 
    if (null == f) 
     throw new IllegalArgumentException("null f"); 

    return new TransformManyIterable<E, T>(iterable, f); 
} 

public interface Func<E, T> { 
    T execute(E e); 
} 

public class TransformManyIterable<TOriginal, TResult> implements Iterable<TResult> { 
    private Iterable<TOriginal> iterable; 
    private Func<TOriginal, Iterable<TResult>> func; 

    public TransformManyIterable(Iterable<TOriginal> iterable, 
      Func<TOriginal, Iterable<TResult>> func) { 
     super(); 
     this.iterable = iterable; 
     this.func = func; 
    } 

    class TransformIterator implements Iterator<TResult> { 
     private Iterator<TOriginal> iterator; 
     private Iterator<TResult> currentIterator; 

     public TransformIterator() { 
      iterator = iterable.iterator(); 
     } 

     @Override 
     public boolean hasNext() { 
      if (currentIterator != null && currentIterator.hasNext()) 
       return true; 
      else { 
       while (iterator.hasNext()) { 
        Iterable<TResult> iterable = func.execute(iterator.next()); 
        if (iterable == null) 
         continue; 
        currentIterator = iterable.iterator(); 
        if (currentIterator.hasNext()) 
         return true; 
       } 
      } 

      return false; 
     } 

     @Override 
     public TResult next() { 
      if (currentIterator != null && currentIterator.hasNext()) 
       return currentIterator.next(); 
      else { 
       while (iterator.hasNext()) { 
        Iterable<TResult> iterable = func.execute(iterator.next()); 
        if (iterable == null) 
         continue; 
        currentIterator = iterable.iterator(); 
        if (currentIterator.hasNext()) 
         return currentIterator.next(); 
       } 
      } 
      throw new NoSuchElementException(); 
     } 

     @Override 
     public void remove() { 
      throw new UnsupportedOperationException(); 
     } 
    } 

    @Override 
    public Iterator<TResult> iterator() { 
     return new TransformIterator(); 
    } 

} 

Cách sử dụng:

Iterable<SomeType> result = transformMany(input, new Func<InputType, Iterable<SomeType>>() { 
     @Override 
     public Iterable<SomeType> execute(InputType e) { 
      return new ArrayList<SomeType>(); 
     } 
    }); 
1

Phương pháp này SelectMany là một phần của LINQ là Net-cụ thể. This question hỏi về một sự cân bằng LINQ cho java. Thật không may, nó không giống như có một tương đương trực tiếp.

6

Nếu bạn có thể lấy dữ liệu vào một số Iterable<Iterable<T>>, thì bạn có thể lấy từ đó thành phẳng Iterable<T> bằng phương pháp Iterables.concat của Guava. Nếu những gì bạn có thực sự là một Iterable<S>, với một số cách để có được từ một S đến một số Iterable<T>, thì, trước tiên bạn phải sử dụng Iterables.transform để xem đó là Iterable<Iterable<T>> cần thiết bởi concat.

Tất cả điều này sẽ đẹp hơn rất nhiều nếu và khi Java có thứ gì đó giống như đóng cửa, nhưng ít nhất là ngày nay nó có thể.

http://guava-libraries.googlecode.com

3

Với Java 8, bạn có thể nói

Collection bunchOfItems = ...; 
bunchOfItems.stream().flatMap(k::getItems).forEach(i -> /* operate on i */); 

hoặc

Item[] bunchOfItems = ...; 
Stream.of(bunchOfItems).flatMap(k::getItems).forEach(i -> /* operate on i */); 

tùy thuộc bạn có một Collection hoặc một Array.

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