2017-01-24 73 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,請考慮默認值。