由于我们的特定需求,我不得不将ResourceBundle子类化。
然而,为了覆盖getKeys(),我遇到了一点麻烦。这个getKeys需要以某种方式从底层ResourceBundle的映射连接起来。我该怎么做呢?
谢谢
编辑:在提交的时候,我想到了一个想法。基本上,我们每个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);
}发布于 2011-12-05 23:06:45
这就是我们最终想出的方案。它有更多的代码,但我认为分享基础知识是公平的。这个解决方案遵循了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;
}
}
}发布于 2011-12-01 06:05:11
最简单的方法是手动枚举枚举,将其转储到一个集合中,然后返回该集合的枚举。
如果做不到这一点,您可以组合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);
}
})
)); 这种方法的好处是高效-它做任何事情都很懒惰,而且直到你要求它才会迭代。不过,在你的情况下,效率可能并不重要,在这种情况下,只需以简单的方式进行即可。
发布于 2014-01-27 23:38:26
您可以使用sun.misc.CompoundEnumeration。它是Java的一部分,不需要额外的库。
https://stackoverflow.com/questions/8333513
复制相似问题