2014-01-24 50 views
1

有了這個代碼:有沒有辦法將鏈表(或地圖)鏈接到for循環?

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語法只是允許鏈接兩個相似的列表並循環它們。

+1

的可能的複製http://stackoverflow.com/questions/3610261/is-it-possible-to-merge-iterators-in-java – zapl

+0

是的,重複。關於該帖子的好消息。 – ilomambo

回答

5

Java本身不支持此行爲。

如果你使用Google Guava那麼你可以這樣做:

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

} 

你也可以敲了一個快速的實用工具類。我在這裏使用了可變參數,以便使用更好;缺點是編譯器會拋出很多警告,因爲通用數組創建和可變參數方法未被選中。

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); 
} 

如果你到那種事情的魔力......

+0

看起來不錯!我不知道番石榴,我會開始學習它。 – ilomambo

+0

不錯的實用! – ilomambo

+0

不應該'CombinedIterable.concat(s1,s2,s3)'是'CombinedIterable .concat(s1,s2,s3)'? – ilomambo

0

板條箱方法,並調用它,只要你想

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); 

地圖的結合總是限制你,你的地圖總是有獨特的按鍵儘可能多的時間。因此,只有在您確定您的密鑰始終是唯一的時才合併。

+0

謝謝Ashish,這也是我在我的問題中提出的想法之一。我其實想知道在java中是否有一些鏈表語法。 – ilomambo

+0

@ilomambo那裏沒有任何列表鏈接方法。但是,如果你不這樣做,你可以將所有值添加到List/Set,然後在單次迭代中執行操作 –

+0

再次感謝您Ashish,這也是我提出的另一個想法(合併)。恐怕迭代器的本質可能會阻止列表的鏈接,並且必須使用其他兩種解決方案之一。只是認爲代碼在鏈接上看起來會更優雅。讓我們等待幾個小時,看看有人有新的信息,如果沒有,我會接受你的答案。 – ilomambo

相關問題