Java';s toLowerCase()是否保留原始字符串长度?

Java';s toLowerCase()是否保留原始字符串长度?,java,string,string-length,Java,String,String Length,假设有两个Java字符串对象: String str = "<my string>"; String strLower = str.toLowerCase(); 计算结果为true 所以,String.toLowerCase()是否为字符串的任何值保留原始字符串长度?令人惊讶的是,它确实没有 来自 使用给定区域设置的规则将此字符串中的所有字符转换为小写。大小写映射基于字符类指定的Unicode标准版本由于大小写映射并不总是1:1字符映射,因此结果字符串的长度可能与原始字符串不同。

假设有两个Java字符串对象:

String str = "<my string>";
String strLower = str.toLowerCase();
计算结果为
true


所以,
String.toLowerCase()
是否为字符串的任何值保留原始字符串长度?

令人惊讶的是,它确实没有

来自

使用给定区域设置的规则将此字符串中的所有字符转换为小写。大小写映射基于字符类指定的Unicode标准版本由于大小写映射并不总是1:1字符映射,因此结果字符串的长度可能与原始字符串不同。

示例:

package com.stackoverflow.q2357315;

import java.util.Locale;

public class Test {
    public static void main(String[] args) throws Exception {
        Locale.setDefault(new Locale("lt"));
        String s = "\u00cc";
        System.out.println(s + " (" + s.length() + ")"); // Ì (1)
        s = s.toLowerCase();
        System.out.println(s + " (" + s.length() + ")"); // i̇̀ (3)
    }
}

首先,我想指出的是,我完全同意@codaddict(目前评分最高)的答案

但我想做一个实验,所以这里是:

这不是一个正式的证明,但是这段代码在运行时从未到达
if
的内部(在Ubuntu上使用JDK 1.6.0 Update 16):

编辑:以下是一些处理区域设置的更新代码:

import java.util.Locale;

public class ToLowerTester {
    public final Locale locale;

    public ToLowerTester(final Locale locale) {
        this.locale = locale;
    }

    public String findFirstStrangeTwoLetterCombination() {
        char[] b = new char[2];
        for (char c1 = 0; c1 < Character.MAX_VALUE; c1++) {
            b[0] = c1;
            for (char c2 = 0; c2 < Character.MAX_VALUE; c2++) {
                b[1] = c2;
                final String string = new String(b);
                String lower = string.toLowerCase(locale);
                if (string.length() != lower.length()) {
                    return string;
                }
            }
        }
        return null;
    }
    public static void main(final String[] args) {
        Locale[] locales;
        if (args.length != 0) {
            locales = new Locale[args.length];
            for (int i=0; i<args.length; i++) {
                locales[i] = new Locale(args[i]);
            }
        } else {
            locales = Locale.getAvailableLocales();
        }
        for (Locale locale : locales) {
            System.out.println("Testing " + locale + "...");
            String result = new ToLowerTester(locale).findFirstStrangeTwoLetterCombination();
            if (result != null) {
                String lower = result.toLowerCase(locale);
                System.out.println("Found strange two letter combination for locale "
                    + locale + ": <" + result + "> (" + result.length() + ") -> <"
                    + lower + "> (" + lower.length() + ")");
            }
        }
    }
}
import java.util.Locale;
公共级托洛维斯特酒店{
公共最终场所;
公共托洛维斯特(最终地点){
this.locale=locale;
}
公共字符串findFirstTransGetWoletterCombination(){
char[]b=新字符[2];
对于(字符c1=0;c1对于(int i=0;i还要记住,toUpperCase()也不保留长度对于德语地区。因此,如果您使用区分大小写的字符串,并且需要存储某些内容的索引,您或多或少会感到不安。

您能举出一些例子吗?我知道几个例子会使大写变量的大小不同于小写变量,例如,
ß
将变成
SS
,但不是ot她一路走来。@BalusC:关于在语言环境AZ、LT和TR中组合字符,有一些奇特的规则,请参见
java/lang/ConditionalSpecialCasing.java
。例如,
“\u00cc”。toLowerCase(新语言环境(“LT”)。length()==3
很酷,谢谢你的指针。我可以在这个答案中自由编辑SSCE。
java/lang/ConditionalSpecialCasing.java
处理这里列出的特殊Unicode情况。你应该知道,你编写的代码依赖于默认的语言环境。不明显,但令人讨厌。因为straße和strasse都是正确的拼写(忽略大写字母S的事实,因为它们是名词),我假设它会产生一个有趣的副作用,即返回大写字母会产生一个不同的字符串?你试过了吗?
import java.util.Locale;

public class ToLowerTester {
    public final Locale locale;

    public ToLowerTester(final Locale locale) {
        this.locale = locale;
    }

    public String findFirstStrangeTwoLetterCombination() {
        char[] b = new char[2];
        for (char c1 = 0; c1 < Character.MAX_VALUE; c1++) {
            b[0] = c1;
            for (char c2 = 0; c2 < Character.MAX_VALUE; c2++) {
                b[1] = c2;
                final String string = new String(b);
                String lower = string.toLowerCase(locale);
                if (string.length() != lower.length()) {
                    return string;
                }
            }
        }
        return null;
    }
    public static void main(final String[] args) {
        Locale[] locales;
        if (args.length != 0) {
            locales = new Locale[args.length];
            for (int i=0; i<args.length; i++) {
                locales[i] = new Locale(args[i]);
            }
        } else {
            locales = Locale.getAvailableLocales();
        }
        for (Locale locale : locales) {
            System.out.println("Testing " + locale + "...");
            String result = new ToLowerTester(locale).findFirstStrangeTwoLetterCombination();
            if (result != null) {
                String lower = result.toLowerCase(locale);
                System.out.println("Found strange two letter combination for locale "
                    + locale + ": <" + result + "> (" + result.length() + ") -> <"
                    + lower + "> (" + lower.length() + ")");
            }
        }
    }
}