在Java中有没有办法从Locale创建Locale.LanguageRange?
目前我这样做:
List<LanguageRange> ranges =
Locale.LanguageRange.parse(
locale.toString() // locale.toString() gives en_GB
.replace('_', '-') // parse() needs en-GB
+ ";q=1.0"); // weight
感觉很脏而且非常不优雅。
有更好的甚至是标准的方法吗?我找不到一个。
最小的工作示例:
import java.util.Collection;
import java.util.List;
import java.util.Locale;
import java.util.Locale.LanguageRange;
public class LanguageUtil {
public static Locale getClosestMatch(Locale locale, Locale defaultLocale, Collection<Locale> allowedLanguages) {
List<LanguageRange> ranges = Locale.LanguageRange.parse(
locale.toString().replace('_', '-') + ";q=1.0," + //exact match e.g. en-GB -> en-GB
locale.getLanguage() + ";q=0.5," + //close match e.g. en-US -> en-GB
defaultLocale.toString().replace('_', '-') + ";q=0.0")); //default match e.g. fr-FR -> en-GB
return Locale.filter(ranges, allowedLanguages).get(0);
}
}
答案 0 :(得分:2)
我使用new LanguageRange(locale.toLanguageTag())
从LanguageRange
派生Locale
来处理语法。
但是,通过将其提供给Locale.lookup()
,匹配是限制性的(en_GB
不会返回en
。
filter
请求的区域设置的所有系统区域设置lookup
第1步结果列表与支持的区域设置的最佳匹配源代码:
List<Locale> allAvailableLocales = Arrays.asList(Locale.getAvailableLocales());
private Locale findBestMatch(final List<Locale> requested, final List<Locale> supported) {
final List<LanguageRange> languageRanges = toLanguageRanges(requested);
final List<Locale> allMatches = Locale.filter(languageRanges, allAvailableLocales);
final Locale bestMatch = Locale.lookup(toLanguageRanges(allMatches), supported);
return bestMatch;
}
private static List<LanguageRange> toLanguageRanges(final List<Locale> locales) {
final ArrayList<LanguageRange> languageRanges = new ArrayList<>();
for (final Locale locale : locales) {
languageRanges.add(toLanguageRange(locale));
}
return languageRanges;
}
private static LanguageRange toLanguageRange(final Locale locale) {
return new LanguageRange(locale.toLanguageTag());
}
注意:如果findBestMatch
返回null
,请考虑默认值。