2017-01-24 44 views
4

在Java中,是否有一种方法可以从Locale创建Locale.LanguageRange?用Java语言环境创建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); 
     } 
    } 

回答

2

我用new LanguageRange(locale.toLanguageTag())Locale这需要语法照顾派生LanguageRange

然而,通过此供给到Locale.lookup()匹配是限制性的(它不会返回en_GBen为)。

因此,我结束了一个两步机制:

  1. filter所有系统语言环境被请求的语言环境
  2. 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,请考虑默认值。