有没有办法在for循环中链接列表(或地图)?

时间:2014-01-24 03:47:38

标签: java loops for-loop

拥有此代码:

Map<String,Rect> map1 = new HashMap<String,Rect>();
Map<String,Rect> map2 = new HashMap<String,Rect>();
...
for( Rect r: map1.values() ) {
    r.offset(10,10);
}
for( Rect r: map2.values() ) {
    r.offset(10,10);
}

如果两个循环中的代码相同,是否有一种简单的方法将两个循环组合成一个循环? (假设所有地图键都不同) 我确实有一些想法也有帮助(比如将两个地图合并到一个地图中或者使用方法以地图作为参数进行循环),但我想知道如果Java语法中有某些东西只允许链接两个相似的列表并循环它们。

2 个答案:

答案 0 :(得分:5)

Java本身不支持此行为。

如果您使用Google Guava,那么您可以这样做:

for (final Rect rect : Iterables.concat(map1.values(), map2.values())) {

}

你也可以敲一个快速的实用课程。我在这里使用了varargs以便使用更好;缺点是编译器将抛出大量警告,因为通用数组创建和varargs方法未经检查。

public class CombinedIterable<T> implements Iterable<T> {

    public static <T> Iterable<T> concat(Iterable<? extends T>... iterables) {
        return new CombinedIterable<T>(iterables);
    }

    private final List<Iterable<? extends T>> iterables;

    private CombinedIterable(Iterable<? extends T>... iterables) {
        this.iterables = Arrays.asList(iterables);
    }

    @Override
    public Iterator<T> iterator() {
        return new Iterator<T>() {

            private final Iterator<Iterable<? extends T>> pos = iterables.iterator();
            private Iterator<? extends T> iter = pos.next().iterator();

            @Override
            public boolean hasNext() {
                if (iter.hasNext()) {
                    return true;
                }
                if (pos.hasNext()) {
                    iter = pos.next().iterator();
                }
                return iter.hasNext();
            }

            @Override
            public T next() {
                return iter.next();
            }

            @Override
            public void remove() {
                throw new UnsupportedOperationException("Not supported.");
            }
        };
    }

}

用法类似于:

final List<String> s1 = Arrays.asList(new String[]{"A", "B", "C"});
final List<String> s2 = Arrays.asList(new String[]{"D", "E", "F"});
final List<String> s3 = Arrays.asList(new String[]{"H", "I", "J"});
for (final String s : CombinedIterable.concat(s1, s2, s3)) {
    System.out.println(s);
}

借助import static

的魔力
for (final String s : concat(s1, s2, s3)) {
    System.out.println(s);
}

如果你遇到那种事情......

答案 1 :(得分:0)

Crate方法并根据需要多次调用

public void updateOffset(Map<String,Rect> map) {
    for( Rect r: map.values() ) {
        r.offset(10,10);
    }
}

现在您的代码变为

Map<String,Rect> map1 = new HashMap<String,Rect>();
Map<String,Rect> map2 = new HashMap<String,Rect>();
...
updateOffset(map1);
updateOffset(map2);

地图的组合始终限制您的地图始终具有唯一键。因此,只有在您确定您的密钥始终是唯一的时才合并。