我想在课堂上保存翻译价值。因为它很方便,Java的Locale
实现似乎是映射的正确键。问题是:如果我只使用HashMap<Locale, String> translations = ...;
进行翻译,那么当特定区域设置不可用时,我的代码将无法回退。
如何实现存储对象翻译的良好数据结构?
请注意,这些翻译不是程序元素的翻译,比如用户界面,想象这个类是字典条目,因此每个类都有自己的翻译量,每次都不同。
以下是HashMap的问题:
import java.util.HashMap;
import java.util.Locale;
public class Example
{
private final HashMap<Locale, String> translationsMap = new HashMap<>();
/*
* +------------------------+-------------------+-------------------+
* | Input | Expected output | Actual output |
* +------------------------+-------------------+-------------------+
* | new Locale("en") | "enTranslation" | "enTranslation" |
* | new Locale("en", "CA") | "enTranslation" | null | <-- Did not fall back
* | new Locale("de") | "deTranslation" | "deTranslation" |
* | new Locale("de", "DE") | "deTranslation" | null | <-- Did not fall back
* | new Locale("de", "AT") | "deATTranslation" | "deATTranslation" |
* | new Locale("fr") | "frTranslation" | "frTranslation" |
* | new Locale("fr", "CA") | "frTranslation" | null | <-- Did not fall back
* +------------------------+-------------------+-------------------+
*/
public String getTranslation(Locale locale)
{
return translationsMap.get(locale);
}
public void addTranslation(Locale locale, String translation)
{
translationsMap.put(locale, translation);
}
// dynamic class initializer
{
addTranslation(new Locale("en"), "enTranslation");
addTranslation(new Locale("de"), "deTranslation");
addTranslation(new Locale("fr"), "frTranslation");
addTranslation(new Locale("de", "AT"), "deATTranslation");
}
}
答案 0 :(得分:0)
这有点hacky,但它确实有效。使用ResourceBundle.Control
,可以使用标准实现进行回退。
private Map<Locale, String> translations = new HashMap<>();
/** static: this instance is not modified or bound, it can be reused for multiple instances */
private static final ResourceBundle.Control CONTROL = ResourceBundle.Control.getControl(ResourceBundle.Control.FORMAT_PROPERTIES);
@Nullable
public String getTranslation(@NotNull Locale locale)
{
List<Locale> localeCandidates = CONTROL.getCandidateLocales("_dummy_", locale); // Sun's implementation discards the string argument
for (Locale currentCandidate : localeCandidates)
{
String translation = translations.get(currentCandidate);
if (translation != null)
return translation;
}
return null;
}
答案 1 :(得分:-1)
让你的课程扩展ListResourceBundle。
见这里:https://docs.oracle.com/javase/tutorial/i18n/resbundle/list.html