diff -r 32d957185656 src/java.base/share/classes/sun/util/locale/LocaleMatcher.java --- a/src/java.base/share/classes/sun/util/locale/LocaleMatcher.java Thu Sep 15 17:15:54 2016 +0000 +++ b/src/java.base/share/classes/sun/util/locale/LocaleMatcher.java Fri Sep 30 17:23:11 2016 +0100 @@ -80,15 +80,14 @@ list = new ArrayList<>(); for (LanguageRange lr : priorityList) { String range = lr.getRange(); - if (range.startsWith("*-") - || range.indexOf("-*") != -1) { // Extended range + if (range.startsWith("*-") || range.contains("-*")) { // Extended range if (mode == AUTOSELECT_FILTERING) { return filterExtended(priorityList, tags); } else if (mode == MAP_EXTENDED_RANGES) { if (range.charAt(0) == '*') { range = "*"; } else { - range = range.replaceAll("-[*]", ""); + range = range.replace("-*", ""); } list.add(new LanguageRange(range, lr.getWeight())); } else if (mode == REJECT_EXTENDED_RANGES) { @@ -365,7 +364,7 @@ continue; } - String rangeForRegex = range.replaceAll("\\x2A", "\\\\p{Alnum}*"); + String rangeForRegex = range.replace("*", "\\\\p{Alnum}*"); while (rangeForRegex.length() > 0) { for (String tag : tags) { tag = tag.toLowerCase(Locale.ROOT); @@ -399,7 +398,7 @@ continue; } - String rangeForRegex = range.replaceAll("\\x2A", "\\\\p{Alnum}*"); + String rangeForRegex = range.replace("*", "\\\\p{Alnum}*"); while (rangeForRegex.length() > 0) { if (tag.matches(rangeForRegex)) { return true; @@ -447,7 +446,7 @@ } public static List parse(String ranges) { - ranges = ranges.replaceAll(" ", "").toLowerCase(Locale.ROOT); + ranges = ranges.replace(" ", "").toLowerCase(Locale.ROOT); if (ranges.startsWith("accept-language:")) { ranges = ranges.substring(16); // delete unnecessary prefix } @@ -536,6 +535,20 @@ return list; } + /** + * Like {@code s.replaceFirst(Pattern.quote(substring), replacement)}, but + * is likely faster. Returns the instance {@code s} if there is no match. + */ + private static String replaceFirstLiteralMatch(String s, String substring, String replacement) { + int pos = s.indexOf(substring); + if (pos == -1) { + return s; + } else { + return s.substring(0, pos) + replacement + s.substring(pos + substring.length()); + } + } + + /** Contents of returned String[] must not be modified. */ private static String[] getEquivalentsForLanguage(String range) { String r = range; @@ -544,13 +557,14 @@ String equiv = LocaleEquivalentMaps.singleEquivMap.get(r); // Return immediately for performance if the first matching // subtag is found. - return new String[] {range.replaceFirst(r, equiv)}; + return new String[] { replaceFirstLiteralMatch(range, r, equiv) }; } else if (LocaleEquivalentMaps.multiEquivsMap.containsKey(r)) { String[] equivs = LocaleEquivalentMaps.multiEquivsMap.get(r); + String[] result = new String[equivs.length]; for (int i = 0; i < equivs.length; i++) { - equivs[i] = range.replaceFirst(r, equivs[i]); + result[i] = replaceFirstLiteralMatch(range, r, equivs[i]); } - return equivs; + return result; } // Truncate the last subtag simply. @@ -578,7 +592,7 @@ int len = index + subtag.length(); if (range.length() == len || range.charAt(len) == '-') { - return range.replaceFirst(subtag, LocaleEquivalentMaps.regionVariantEquivMap.get(subtag)); + return replaceFirstLiteralMatch(range, subtag, LocaleEquivalentMaps.regionVariantEquivMap.get(subtag)); } } }