2010-05-06 19 views
6

The question but in C#. Alors Java a-t-il la commande C#? J'en ai besoin pour la relation Matches-SearchTerm-Files.Java: parcourir la liste des listes?

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

[Pourquoi pas-boucles?] je l'ai fait ces structures imbriquées pour les boucles, mais ils deviennent bientôt pléthorique. Donc je préfère quelque chose de plus succint comme ci-dessus.

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

Cette bibliothèque a une implémentation selectMany() qui ressemblerait à ceci pour vos besoins: for (val i: BunchOfItems.selectMany (bunchItemSelector()) {}. Voir https://github.com/nicholas22/jpropel-light –

Répondre

1

avez environ une demi-patience année jusqu'à ce que JDK7 est définitive qui comprendra Closures. Ceci fournit une syntaxe similaire et les mêmes possibilités que LINQ qui a été démontré dans la réponse dont vous parlez.

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

Je ne pense pas qu'il y ait une solution plus simple.

+0

L'OP demande une solution de type Linq que fournit C# Il sait déjà comment parcourir les listes Il veut une solution élégante Malheureusement, Java n'a pas d'équivalent à Linq. –

1

J'ai ma propre version. En attendant désespérément Closures en 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(); 
    } 

} 

Utilisation:

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

La méthode SelectMany fait partie de LINQ qui est .Net spécifique. This question demande à propos d'un équivalent LINQ pour Java. Malheureusement, il ne semble pas y avoir d'équivalent direct.

6

Si vous pouvez obtenir les données dans un Iterable<Iterable<T>>, vous pouvez obtenir à partir de cela à Iterable<T> aplati en utilisant la méthode Iterables.concat de Guava. Si ce que vous avez est vraiment un Iterable<S>, avec un certain moyen de passer d'un S à un Iterable<T>, eh bien, alors vous devez d'abord utiliser Iterables.transform pour voir cela comme le Iterable<Iterable<T>> requis par concat.

Tout cela sera beaucoup plus agréable si et quand Java a quelque chose qui ressemble à des fermetures, mais au moins c'est aujourd'hui possible.

http://guava-libraries.googlecode.com

3

Avec Java 8, vous pouvez dire

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

ou

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

selon que vous avez un Collection ou un Array.