简体   繁体   English

Java:迭代列表列表?

[英]Java: iterating through list of lists?

The question but in C#. 问题,但在C#。 So does Java have C#'s command? 那么Java有C#的命令吗? I need it for Matches-SearchTerm-Files-relationship. 我需要它用于Matches-SearchTerm-Files-relationship。

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

[Why not for-loops?] I have done such structures in nested for loops but they soon become bloated. [为什么不for循环?]我已经在嵌套for循环中完成了这样的结构,但它们很快变得臃肿。 So I prefer something more succint like the above. 所以我更喜欢像上面这样的更多傻瓜。

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;
}
for (List<Object> lo : list) {
    for (Object o : lo) {
        // etc etc
    }
}

I don't think there's a simpler solution. 我不认为有一个更简单的解决方案。

If you can get the data into an Iterable<Iterable<T>> , then you can get from that to a flattened Iterable<T> using Guava's Iterables.concat method. 如果您可以将数据转换为Iterable<Iterable<T>> ,那么您可以使用Guava的Iterables.concat方法从中获得平坦的Iterable<T> If what you have is really an Iterable<S> , with some way to get from an S to an Iterable<T> , well, then you have to first use Iterables.transform to view that as the Iterable<Iterable<T>> needed by concat . 如果你拥有的是一个Iterable<S> ,有一些方法可以从SIterable<T> ,那么你必须首先使用Iterables.transform来查看它作为Iterable<Iterable<T>> concat需要。

All this will look a lot nicer if and when Java has something resembling closures, but at least today it's possible. 如果Java有类似闭包的东西,所有这些看起来会更好,但至少在今天它是可能的。

http://guava-libraries.googlecode.com http://guava-libraries.googlecode.com

With Java 8, you can say 使用Java 8,你可以说

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

or 要么

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

depending upon whether you have a Collection or an Array . 取决于您是否具有CollectionArray

I have my own version. 我有自己的版本。 Waiting desperately for Closures in Java : 拼命地等待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();
    }

}

Usage: 用法:

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

The SelectMany method is part of LINQ which is .Net-specific. SelectMany方法是LINQ的一部分,它是.Net特定的。 This question asks about a LINQ equilvalent for java. 这个问题询问了java的LINQ等价。 Unfortunately, it doesn't look like there is a direct equivalent. 不幸的是,它看起来并不像是直接的等价物。

Have about half a year patience until JDK7 is final which will include Closures . 有大约半年的耐心,直到JDK7最终将包括闭包 This provides simliar syntax and the same possibilities as LINQ which was demonstrated in the answer you're talking about. 这提供了类似于LINQ的语法和相同的可能性,这在您正在讨论的答案中得到了证明。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM