2011-11-30 37 views
1

由於我們的特殊需求,我不得不繼承ResourceBundle連接幾個枚舉?

但是,要覆蓋getKeys(),我有點麻煩。這getKeys需要以某種方式連接從底層ResourceBundle s的地圖。我怎樣才能做到這一點?

謝謝

編輯:雖然提交我碰到一個想法。基本上,我們有我們的每一個Module一個ResourceBundle的,所以我的代碼看起來像這樣至今:

public Enumeration<String> getKeys() { 
     ArrayList<String> keys = new ArrayList<String>(); 

     for (Map.Entry<Module, ResourceBundle> entry : internalMap.entrySet()) { 
      Enumeration<String> tmp = entry.getValue().getKeys(); 
      while (tmp.hasMoreElements()) { 
       String key = tmp.nextElement(); 
       keys.add(key); 
      } 
     } 

     return Collections.enumeration(keys); 
    } 
+0

你能發佈你的代碼嗎? –

回答

0

這就是我們終於想到的。有更多的代碼,但認爲分享基礎是公平的。解決方案有一些skaffman的建議。 感謝所有的貢獻。

public class ChainedResourceBundle extends ResourceBundle implements Enumeration<String> { 

    Iterator<Map.Entry<Module, ResourceBundle>> tables; 
    private Enumeration<String>     keys; 

    private Map<Module, ResourceBundle>   internalMap = new HashMap<Module, ResourceBundle>(); 
    private Map<String, String>     customizedKeys = new HashMap<String, String>(); 


    @Override 
    public Enumeration<String> getKeys() { 
     tables = internalMap.entrySet().iterator(); 
     nextTable(); 
     return this; 
    } 


    @Override 
    public boolean hasMoreElements() { 
     return keys != null; 
    } 


    @Override 
    public String nextElement() { 
     String key = keys.nextElement(); 
     if (!keys.hasMoreElements()) { 
      nextTable(); 
     } 
     return key; 
    } 

    private void nextTable() { 
     if (tables.hasNext()) { 
      keys = tables.next().getValue().getKeys(); 
     } else { 
      keys = null; 
     } 
    } 

} 
2

最簡單的方法就是手動枚舉枚舉,其轉儲到一個集合,然後返回的枚舉那個集合。

如果做不到這一點,你可以結合Google Guava操作要做到這一點,是這樣的:

// the map of enumerations 
Map<?, Enumeration<String>> map = ... 

// a function that turns enumerations into iterators 
Function<Enumeration<String>, Iterator<String>> eumerationToIteratorFunction = new Function<Enumeration<String>, Iterator<String>>() { 
    public Iterator<String> apply(Enumeration<String> enumeration) { 
     return Iterators.forEnumeration(enumeration); 
    } 
}; 

// transform the enumerations into iterators, using the function 
Collection<Iterator<String>> iterators = Collections2.transform(map.values(), eumerationToIteratorFunction); 

// combine the iterators 
Iterator<String> combinedIterator = Iterators.concat(iterators); 

// convert the combined iterator back into an enumeration 
Enumeration<String> combinedEnumeration = Iterators.asEnumeration(combinedIterator); 

這是非常繁瑣的,但Enumeration是舊的和現代的API,而支持甚少。明智地使用靜態導入可以減少一點。你甚至可以做整個事情在一個函數式的語句:

Map<?, Enumeration<String>> map = ... 

Enumeration<String> combinedEnumeration = asEnumeration(concat(
    transform(map.values(), new Function<Enumeration<String>, Iterator<String>>() { 
     public Iterator<String> apply(Enumeration<String> enumeration) { 
     return forEnumeration(enumeration); 
     } 
    }) 
)); 

這種方法被有效的利益 - 但這一切懶洋洋的,不會重複,直到你問它。儘管在這種情況下效率可能並不重要,但在這種情況下,只需簡單的方法即可。

+0

是的,枚舉是這樣一箇舊的接口,可能@fablife應該發送一個MethodNotSupportedException。它很可能永遠不會被調用。 – toto2

+0

最後我們沿着這些線做了一些事情,雖然有點不同。我們實現了一個自己的ResourceBundle,它在單個枚舉上保存了一個迭代器集合並實現了Enumeration。因此,我們可以在需要時生成枚舉。感謝所有貢獻者。 – faboolous

0

您可以創建自己的定製Enumeration實現,該實現將具有addAll (Enumeration<E> enumeration)方法。然後在所有相關的ResourceBundle對象上調用getKeys(),並將它們全部添加到您自己的Enumeration的新實例中。

0

你可以使用Guava's Iterators類:變換使用forEnumeration,然後concat迭代器的每個枚舉,並變換所產生的迭代器重新使用asEnumeration枚舉。

或者使用類似於Guava的concat方法的代碼自己實現一個串聯Enumeration。

2

您可以使用sun.misc.CompoundEnumeration。它是Java的一部分,不需要額外的庫。