String.toLowerCase(Locale.ROOT)
环境:jdk1.8
Locale是针对区域的转换规则
首先看到Locale类中的ROOT是用两个空字符串初始化的对象,表示所有语言环境的基本语言环境,并且用于语言/国家无关的区域设置,用于区域设置敏感的操作。
/**
* Useful constant for the root locale. The root locale is the locale whose
* language, country, and variant are empty ("") strings. This is regarded
* as the base locale of all locales, and is used as the language/country
* neutral locale for the locale sensitive operations.
*
* @since 1.6
*/
static public final Locale ROOT = createConstant("", "");
部分语种和区域属性
/** Useful constant for language.
*/
static public final Locale JAPANESE = createConstant("ja", "");
/** Useful constant for language.
*/
static public final Locale KOREAN = createConstant("ko", "");
/** Useful constant for language.
*/
static public final Locale CHINESE = createConstant("zh", "");
/** Useful constant for language.
*/
static public final Locale SIMPLIFIED_CHINESE = createConstant("zh", "CN"); // 中国简体
/** Useful constant for language.
*/
static public final Locale TRADITIONAL_CHINESE = createConstant("zh", "TW"); // 中国繁体
/** Useful constant for country.
*/
static public final Locale FRANCE = createConstant("fr", "FR");
/** Useful constant for country.
*/
static public final Locale GERMANY = createConstant("de", "DE");
/** Useful constant for country.
*/
static public final Locale ITALY = createConstant("it", "IT");
/** Useful constant for country.
*/
static public final Locale JAPAN = createConstant("ja", "JP");
/** Useful constant for country.
*/
static public final Locale KOREA = createConstant("ko", "KR");
来看看String转小写的无参方法
public String toLowerCase() {
return toLowerCase(Locale.getDefault()); // 最终调用的都是有参转小写
}
// 这里调用Locale的initDefault获取Locale
private static Locale initDefault() {
String language, region, script, country, variant;
language = AccessController.doPrivileged(
new GetPropertyAction("user.language", "en")); // 获取主机的语种
// for compatibility, check for old user.region property
region = AccessController.doPrivileged(
new GetPropertyAction("user.region")); // 获取主机的区域
if (region != null) {
// region can be of form country, country_variant, or _variant
int i = region.indexOf('_');
if (i >= 0) {
country = region.substring(0, i);
variant = region.substring(i + 1);
} else {
country = region;
variant = "";
}
script = "";
} else {
script = AccessController.doPrivileged(
new GetPropertyAction("user.script", ""));
country = AccessController.doPrivileged(
new GetPropertyAction("user.country", ""));
variant = AccessController.doPrivileged(
new GetPropertyAction("user.variant", ""));
}
return getInstance(language, script, country, variant, null);
}
上面的获取语种和区域,在中国大陆大部分是 -Duser.language=“zh” \ -Duser.region=“CN” \
也就是对应的
static public final Locale SIMPLIFIED_CHINESE = createConstant("zh", "CN");
来看看String转小写的最终方法:
public String toLowerCase(Locale locale) {
if (locale == null) {
throw new NullPointerException();
}
int firstUpper;
final int len = value.length;
/* Now check if there are any characters that need to be changed. */
scan: {
for (firstUpper = 0 ; firstUpper < len; ) {
char c = value[firstUpper];
if ((c >= Character.MIN_HIGH_SURROGATE)
&& (c <= Character.MAX_HIGH_SURROGATE)) {
int supplChar = codePointAt(firstUpper);
if (supplChar != Character.toLowerCase(supplChar)) {
break scan;
}
firstUpper += Character.charCount(supplChar);
} else {
if (c != Character.toLowerCase(c)) {
break scan;
}
firstUpper++;
}
}
return this;
}
char[] result = new char[len];
int resultOffset = 0; /* result may grow, so i+resultOffset
* is the write location in result */
/* Just copy the first few lowerCase characters. */
System.arraycopy(value, 0, result, 0, firstUpper);
String lang = locale.getLanguage();
boolean localeDependent =
(lang == "tr" || lang == "az" || lang == "lt");
char[] lowerCharArray;
int lowerChar;
int srcChar;
int srcCount;
for (int i = firstUpper; i < len; i += srcCount) {
srcChar = (int)value[i];
if ((char)srcChar >= Character.MIN_HIGH_SURROGATE
&& (char)srcChar <= Character.MAX_HIGH_SURROGATE) {
srcChar = codePointAt(i);
srcCount = Character.charCount(srcChar);
} else {
srcCount = 1;
}
if (localeDependent ||
srcChar == '\u03A3' || // 希腊大写字母
srcChar == '\u0130') { // 拉丁文大写字母I上面带点
lowerChar = ConditionalSpecialCasing.toLowerCaseEx(this, i, locale);
} else {
lowerChar = Character.toLowerCase(srcChar);
}
if ((lowerChar == Character.ERROR)
|| (lowerChar >= Character.MIN_SUPPLEMENTARY_CODE_POINT)) {
if (lowerChar == Character.ERROR) {
lowerCharArray =
ConditionalSpecialCasing.toLowerCaseCharArray(this, i, locale);
} else if (srcCount == 2) {
resultOffset += Character.toChars(lowerChar, result, i + resultOffset) - srcCount;
continue;
} else {
lowerCharArray = Character.toChars(lowerChar);
}
/* Grow result if needed */
int mapLen = lowerCharArray.length;
if (mapLen > srcCount) {
char[] result2 = new char[result.length + mapLen - srcCount];
System.arraycopy(result, 0, result2, 0, i + resultOffset);
result = result2;
}
for (int x = 0; x < mapLen; ++x) {
result[i + resultOffset + x] = lowerCharArray[x];
}
resultOffset += (mapLen - srcCount);
} else {
result[i + resultOffset] = (char)lowerChar;
}
}
return new String(result, 0, len + resultOffset);
}
从上面toLowerCase方法中
boolean localeDependent =
(lang == "tr" || lang == "az" || lang == "lt");
这一行看出,转小写的方法只对小部分的特殊语种做了处理
总结
没有特殊语种的情况直接使用无参toLowerCase即可,性能方面我没有做研究,有兴趣的可以去比较一下