2014-02-05 38 views
4

我有一個類Foo爲此我做了一個等價包裝類WrappedFoo在程序的某些部分更改它的equals()合同。如何在Java中包裝Collection的每個對象?

我需要將Foo對象轉換爲WrappedFoo對象,反之亦然。但我也需要將Foo s和WrappedFooCollection s從一個轉換爲另一個。有什麼辦法可以以通用的方式實現這一點?

基本上我想,像這樣的方法:

public static Collection<WrappedFoo> wrapCollection(Collection<Foo> collection) 

的問題是,我不知道會用什麼樣的Collection實施,我想保持相同的實施所產生的Collection

+0

NB:'Collection'是'interface',因此有'執行(一個或多個)',而不是 「子類」。 – Alnitak

+0

@Alnitak糾正;)謝謝 – qwertzguy

回答

2

使用反射API,你可以做這樣的事情(注意方法名中的0):

public static Collection<WrapperFoo> wrapCollection0(Collection<Foo> src) 
{ 
    try 
    { 
     Class<? extends Collection> clazz = src.getClass(); 
     Collection dst = clazz.newInstance(); 
     for (Foo foo : src) 
     { 
      dst.add(new WrapperFoo(foo)); 
     } 
     return dst; 
    } catch(Exception e) 
    { 
     e.printStackTrace(); 
     return null; 
    } 
} 

現在實現使用上述方法一大堆的一行超載方法(注意0在電話):

public static ArrayList<WrapperFoo> wrapCollection(ArrayList<Foo> src) 
{ 
    return (ArrayList<WrapperFoo>) wrapCollection0(src); 
} 

public static Vector<WrapperFoo> wrapCollection(Vector<Foo> src) 
{ 
    return (Vector<WrapperFoo>) wrapCollection0(src); 
} 

... 
+0

這基本上是我提出的兩個解決方案,但他們都是不理想的:我寧願不必寫一堆類似的方法,我寧願避免使用反射。我想看看是否有更好的解決方案。如果沒有人找到更好的解決方案,我會接受這個答案。 – qwertzguy

+0

其實反映並不是那麼糟糕。同時嘗試兩種方法。等一下,我會編輯我的答案。 –

+0

是的,的確沒有那麼糟糕,似乎是現在最好的解決方案。如果一個特定的Collection實現沒有args構造函數,它會中斷,但我想這很少見。 – qwertzguy

1

也許來自谷歌番石榴庫Collections2.transform可能會提供你正在尋找的功能。

您應該能夠傳遞一個函數,將Woo元素包裹在WrappedFoo中。主要問題是新集合是否可以成爲原始集合的視圖(因此它不會與原始集合具有相同的實現)。

+2

transform()返回一個通用'Collection '不是具體的集合類型。我對OP的要求的理解是,通過'List '得到一個'List ' – Kent

+0

@Kent我認爲我的答案是適當的,因爲這個方法匹配他的方法簽名。我確實通過提及它返回視圖集合來限定我的答案。 – Mark

2

Collection-Interface保證存在「boolean addAll(Collection c)」 - 方法。 我只是嘗試一些沿theese線:

public static Collection<WrappedFoo> wrapFoos(Collection<Foo> col) { 
    Class<?> colClass = col.getClass(); 
    Collection<WappedFoo> newCol = colClass.getConstructor().getInstance(); 
    newCol.addAll(col); 
    return newCol; 
} 
+0

因爲'WrappedFoo'沒有擴展'Foo',所以我不能'addAll()'。但是,做一個循環並添加它們並調用將'Foo'包裝到'WrappedFoo'中的方法應該可行。然後,這匹配@Martijn Courteaux的答案。這只是我想避免使用反思。 – qwertzguy

+0

你是對的,包裝需要明確完成。不過,我認爲你不會繞過反射,因爲你想保持原始的集合實現,所以你可以在不需要從原始集合類實例化的情況下實例化集合。 – TreffnonX

相關問題