2009-11-15 49 views
5

是否有表示集合與另一個集合串聯的類?這個類本身應該是一個集合,並且應該將所有方法委託給底層(內部)集合 - 不應該分配額外的內存,也不應修改任何原始集合。代表Java中兩個集合串聯的集合

用法示例:

Collection<String> foo = ... 
Collection<String> bar = ... 

// this should be O(1) memory and time 
Collection<String> combined = concat(foo, bar); 

if (combined.contains("Zee")) 
    ... 

for (String str : combined) 
    System.out.println(str); 
+0

你的意思是像Python的itertools提供的東西? – 2009-11-15 16:53:54

+0

如果您想要一個表示集合和項目,兩個集合或類別的類,則不太清楚。 – Jack 2009-11-15 17:01:39

+0

表示兩個集合串聯的類。 – ripper234 2009-11-15 17:03:58

回答

0

我不知道你的要價。我對你的問題的解釋是你正在尋找Collection的add方法。我不認爲你就是這麼問。

+0

我正在尋找一個集合,它封裝了兩個集合的連接,_without_分配了大量內存或修改了原始集合。 – ripper234 2009-11-15 17:02:32

4

你的問題非常模糊。特別是「與另一個項目另一個集合」是相當不清楚。

您至少可以使用Collection#addAll()將另一個Collection的內容添加到當前的Collection中。這裏Collection可以是其子接口/實現的任何東西,例如, ListSet

例子:

List<String> foos = Arrays.asList("foo1", "foo2", "foo3"); 
List<String> bars = Arrays.asList("bar1", "bar2", "bar3"); 
foos.addAll(bars); // Now foos contains everything. 

編輯:還是你真的想創建一個新Collection基於現有Collection,然後添加一個新的項目呢?在這種情況下,只需構建一個新的Collection,將現有的Collection作爲構造函數參數。例如: -

List<String> foos = Arrays.asList("foo1", "foo2", "foo3"); 
List<String> bars = new ArrayList<String>(foos); 
bars.add("bar"); // Now bars contains everything. 
+0

我總是比較喜歡本地Java庫的方式去做第三方庫之前的事情。 – 2013-03-04 21:36:36

2

我想你問的是一個Java結構,使您可以把集合在一起,沒有修改原始集合。換句話說,你有收藏A和B,分別是N和M的大小。在concat調用之後,仍然有集合A和B,它們的大小仍然是N和M,但是您也有集合C以及指向A和B的集合C,從而使其大小爲N + M。

答案是否定的,Java沒有任何開箱即可做到這一點...但是,您可以編寫一個快速封裝器,它包裝一系列集合並將這些集合添加到它。 (它只會維護對每個集合的引用),並且可以根據需要公開get/insert方法。

+0

這確實是我正在尋找...正在考慮是否有這樣一個圖書館。 – ripper234 2009-11-15 17:58:27

9

一如既往的收集東西,看看google-collections。如果你有Set S,具體爲(不僅僅是一般的集合),你想:

Set<String> combined = Sets.union(foo, bar); 

它創建兩套不可修改視圖。也就是說,foobar中的更改將反映在combined(但不支持combined.add()等)。

對於更一般的情況,你有Iterables.concat()但只允許你迭代加入的項目,Iterable界面顯然不包括contains,所以你有點弄髒。

谷歌集合中的其他集合實用程序類(com.google.common.collect.Listscom.google.common.collect.Collections2)不包含任何連接方法。不明白爲什麼他們不能,但目前他們沒有。

+4

我們發現,99%的時間,用戶真的只需要迭代。因此Iterables.concat()。在內部,我們也有一個Lists.concat(),但是任何人都使用它,而且大多數人可能只是使用另一個。 – 2009-11-18 08:15:41

3

沒有,但寫它自己應該直截了當

package ch.akuhn.util; 

import java.util.Iterator; 
import java.util.NoSuchElementException; 

public class Concat { 

    public static <T> Iterable<T> all(final Iterable<T>... iterables) { 
     return new Iterable<T>() { 
      @Override 
      public Iterator<T> iterator() { 
       return new Iterator<T>() { 
        Iterator<Iterable<T>> more = Arrays.asList(iterables).iterator(); 
        Iterator<T> current = more.hasNext() ? more.next().iterator() : null; 
        @Override 
        public boolean hasNext() { 
         if (current == null) return false; 
         if (current.hasNext()) return true; 
         current = more.hasNext() ? more.next().iterator() : null; 
         return this.hasNext(); 
        } 

        @Override 
        public T next() { 
         if (!hasNext()) throw new NoSuchElementException(); 
         return current.next(); 
        } 

        @Override 
        public void remove() { 
         throw new UnsupportedOperationException(); 
        } 
       }; 
      } 
     }; 
    } 

} 

然後

for (Object each: Concat.all(collection,whatever,etcetera,...)) { 
    // ... 
} 

這裏只是寫了這個代碼,編譯風險自負!

PS,如果你要爲這個班級編寫單元測試,請發送給我。