由于我们的特殊需要,我必须继承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);
}
答案 0 :(得分:3)
最简单的方法是手动枚举枚举,将它们转储到集合中,然后返回该集合的枚举。
如果做不到这一点,您可以将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);
}
})
));
这种方法具有高效的好处 - 它可以懒惰地完成所有操作,并且在您提出要求之前不会进行迭代。在你的情况下,效率可能无关紧要,在这种情况下,只需简单的方法就可以了。
答案 1 :(得分:2)
您可以使用sun.misc.CompoundEnumeration。它是Java的一部分,无需额外的库。
答案 2 :(得分:0)
您可以使用Enumeration
方法创建自己的自定义addAll (Enumeration<E> enumeration)
实施。然后在所有基础getKeys()
对象上调用ResourceBundle
,并将它们全部添加到您自己Enumeration
的新实例中。
答案 3 :(得分:0)
您可以使用Guava's Iterators class:使用forEnumeration
转换每个枚举,然后使用concat
迭代器转换,并使用asEnumeration
将生成的迭代器转换回枚举。
或者使用类似于Guava的concat方法的代码自己实现连接枚举。
答案 4 :(得分: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;
}
}
}
答案 5 :(得分:0)
您也可以像
一样使用Vector
public Enumeration<String> getKeys() {
ResourceBundle parent = this.parent;
Set<String> keySet = this.handleKeySet();
List<String> parentKeySet = (parent != null) ? list(parent.getKeys()) : null;
keySet.addAll(parentKeySet);
return new Vector<>(keySet).elements();
}