2010-05-06 13 views
6

The question but in C#. Quindi Java ha il comando di C#? Mi serve per la relazione Matches-SearchTerm-Files.Java: iterando nell'elenco delle liste?

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

[perché non per-loop?] ho fatto tali strutture in cicli for innestati ma presto diventerà gonfio. Quindi preferisco qualcosa di più simile a quanto sopra.

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

Questa libreria ha un'implementazione selectMany() che dovrebbe assomigliare a questo per il vostro requisito: for (val i: BunchOfItems.selectMany (bunchItemSelector()) {}. Vedere https://github.com/nicholas22/jpropel-light –

risposta

1

hanno circa la metà di un anno fino pazienza JDK7 è definitiva che includerà Closures. Questo fornisce la sintassi similare e le stesse possibilità di LINQ che sono state dimostrate nella risposta di cui stai parlando.

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

Io non credo che ci sia una soluzione più semplice.

+0

L'OP sta chiedendo una soluzione di tipo Linq fornita da C#, che sa già come iterare attraverso le liste, vuole una soluzione elegante, ma sfortunatamente, Java non ha qualcosa di equivalente a Linq. –

1

Ho la mia versione. In attesa disperatamente chiusure in 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(); 
    } 

} 

utilizzo:

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

Il metodo SelectMany fa parte di LINQ che è Net-specifica. This question chiede informazioni su un valore LINQ equi- valente per java. Sfortunatamente, non sembra che ci sia un equivalente diretto.

6

Se è possibile ottenere i dati in un Iterable<Iterable<T>>, è possibile ottenere da questo a Iterable<T> appiattito utilizzando il metodo Iterables.concat di Guava. Se quello che hai è davvero un Iterable<S>, con un modo per passare da uno S a uno Iterable<T>, beh, allora devi prima usare Iterables.transform per vederlo come il Iterable<Iterable<T>> necessario per concat.

Tutto questo sembrerà molto più bello se e quando Java ha qualcosa che assomiglia alle chiusure, ma almeno oggi è possibile.

http://guava-libraries.googlecode.com

3

con Java 8, si può dire

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

o

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

a seconda se si dispone di un Collection o un Array.

Problemi correlati