2011-11-30 39 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的一部分,不需要额外的库。