diff options
author | vichang <vichang@google.com> | 2021-04-30 14:03:05 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2021-04-30 14:03:05 +0000 |
commit | 4b95112d4e6042e46e5f53c38b120b39146f91f3 (patch) | |
tree | 0a0fa59f6064413c09b3dc968d84698dc4493d8f | |
parent | 0be863c8690ce683c6de7e3fe3c45ed46a5b02d0 (diff) | |
parent | e7e36af1b0d1478c92b3dde5f7440967c1ad829a (diff) | |
download | icu-4b95112d4e6042e46e5f53c38b120b39146f91f3.tar.gz |
Merge "Cherry-pick: ICU-21567 Avoid using regex in ULocale.getName()"
-rw-r--r-- | android_icu4j/src/main/java/android/icu/util/ULocale.java | 35 | ||||
-rw-r--r-- | icu4j/main/classes/core/src/com/ibm/icu/util/ULocale.java | 35 |
2 files changed, 62 insertions, 8 deletions
diff --git a/android_icu4j/src/main/java/android/icu/util/ULocale.java b/android_icu4j/src/main/java/android/icu/util/ULocale.java index 1339cb686..466b01a8b 100644 --- a/android_icu4j/src/main/java/android/icu/util/ULocale.java +++ b/android_icu4j/src/main/java/android/icu/util/ULocale.java @@ -29,7 +29,6 @@ import java.util.Objects; import java.util.Set; import java.util.TreeMap; import java.util.TreeSet; -import java.util.regex.Pattern; import android.icu.impl.CacheBase; import android.icu.impl.ICUData; @@ -106,8 +105,6 @@ public final class ULocale implements Serializable, Comparable<ULocale> { // using serialver from jdk1.4.2_05 private static final long serialVersionUID = 3715177670352309217L; - private static final Pattern UND_PATTERN = Pattern.compile("^und(?=$|[_-])", Pattern.CASE_INSENSITIVE); - private static CacheBase<String, String, Void> nameCache = new SoftCache<String, String, Void>() { @Override protected String createInstance(String tmpLocaleID, Void unused) { @@ -1064,12 +1061,42 @@ public final class ULocale implements Serializable, Comparable<ULocale> { } else if ("root".equalsIgnoreCase(localeID)) { tmpLocaleID = EMPTY_STRING; } else { - tmpLocaleID = UND_PATTERN.matcher(localeID).replaceFirst(EMPTY_STRING); + tmpLocaleID = stripLeadingUnd(localeID); } return nameCache.getInstance(tmpLocaleID, null /* unused */); } /** + * Strips out the leading "und" language code case-insensitively. + * + * @implNote Avoids creating new local non-primitive objects to reduce GC pressure. + */ + private static String stripLeadingUnd(String localeID) { + int length = localeID.length(); + if (length < 3) { + return localeID; + } + + // If not starts with "und", return. + if (!localeID.regionMatches(/*ignoreCase=*/true, 0, "und", 0, /*len=*/3)) { + return localeID; + } + + // The string is equals to "und" case-insensitively. + if (length == 3) { + return EMPTY_STRING; + } + + // localeID must have a length >= 4 + char separator = localeID.charAt(3); + if (separator == '-' || separator == '_') { // "und-*" or "und_*" + return localeID.substring(3); + } + + return localeID; + } + + /** * Returns a string representation of this object. * @return a string representation of the object. */ diff --git a/icu4j/main/classes/core/src/com/ibm/icu/util/ULocale.java b/icu4j/main/classes/core/src/com/ibm/icu/util/ULocale.java index 9faa3c444..7a6586ec4 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/util/ULocale.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/util/ULocale.java @@ -28,7 +28,6 @@ import java.util.Objects; import java.util.Set; import java.util.TreeMap; import java.util.TreeSet; -import java.util.regex.Pattern; import com.ibm.icu.impl.CacheBase; import com.ibm.icu.impl.ICUData; @@ -119,8 +118,6 @@ public final class ULocale implements Serializable, Comparable<ULocale> { // using serialver from jdk1.4.2_05 private static final long serialVersionUID = 3715177670352309217L; - private static final Pattern UND_PATTERN = Pattern.compile("^und(?=$|[_-])", Pattern.CASE_INSENSITIVE); - private static CacheBase<String, String, Void> nameCache = new SoftCache<String, String, Void>() { @Override protected String createInstance(String tmpLocaleID, Void unused) { @@ -1145,12 +1142,42 @@ public final class ULocale implements Serializable, Comparable<ULocale> { } else if ("root".equalsIgnoreCase(localeID)) { tmpLocaleID = EMPTY_STRING; } else { - tmpLocaleID = UND_PATTERN.matcher(localeID).replaceFirst(EMPTY_STRING); + tmpLocaleID = stripLeadingUnd(localeID); } return nameCache.getInstance(tmpLocaleID, null /* unused */); } /** + * Strips out the leading "und" language code case-insensitively. + * + * @implNote Avoids creating new local non-primitive objects to reduce GC pressure. + */ + private static String stripLeadingUnd(String localeID) { + int length = localeID.length(); + if (length < 3) { + return localeID; + } + + // If not starts with "und", return. + if (!localeID.regionMatches(/*ignoreCase=*/true, 0, "und", 0, /*len=*/3)) { + return localeID; + } + + // The string is equals to "und" case-insensitively. + if (length == 3) { + return EMPTY_STRING; + } + + // localeID must have a length >= 4 + char separator = localeID.charAt(3); + if (separator == '-' || separator == '_') { // "und-*" or "und_*" + return localeID.substring(3); + } + + return localeID; + } + + /** * Returns a string representation of this object. * @return a string representation of the object. * @stable ICU 2.8 |