Java - 用于存储和获取翻译的数据结构(作为对象属性)

时间:2015-10-23 11:02:05

标签: java data-structures internationalization locale

我想在课堂上保存翻译价值。因为它很方便,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");
    }
}

2 个答案:

答案 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