はJavaのtoLowerCase()保存元の文字列すか?
-
23-09-2019 - |
質問
ふたつのJavaのStringオブジェクト:
String str = "<my string>";
String strLower = str.toLowerCase();
はそのう毎に価値の <my string>
表現
str.length() == strLower.length()
評価 true
?
なので、 String.toLowerCase()
保元の文字列長のための任意の値の文字列?
解決
驚くことにな ない!!
Java docsの 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の(現在の最高の定格)の答えに同意することを指摘したいと思います。
しかし、私は、実験をやってみたかったので、ここでは、次のとおりです。
<ストライキ>それは(Ubuntuの上でJDK 1.6.0アップデート16を使用して)今までif
の内部に到達することなく、正式な証拠が、私のために、このコード走ったではありません。ストライキ>
の編集をここにいくつか更新されたコードがあることだハンドルロケールのほかます:
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() + ")");
}
}
}
}
受け入れ答えで述べたロケール名とそのコードを実行すると、いくつかの例を表示します。引数なしで実行すると、すべての使用可能なロケールを試してみてください(と、かなり時間がかかる!)されます。
理論的には複数文字の文字列があるかもしれないので、<ストライキが>それは振る舞いが異なり、それは良い第一近似だと、広範囲ではありません。ストライキ>
2文字の組み合わせの多くがこのように作らことにも注意してください、このコードでは何も爆発はJavaだけでは非常に強力な文字列APIのせいにすることができるという事実ので、おそらく無効なUTF-16です。
少なくとも最後のではなく、そして:仮定は、Javaの現在の実装のために真である場合でも、Javaの将来のバージョンは、新しい文字のためのルールが状況を紹介しているUnicode標準の将来のバージョンを、実装したら、簡単に変更することができますこれはもはや当てはまります。
だから、これに応じて、まだかなり悪い考えです。
またtoUpperCaseのは、()のいずれかの長さを保持していないことを覚えておいてください。例:「STRASSEは」ドイツ語のロケールのために「STRASSE」になります。あなたは大文字と小文字を区別した文字列で作業している場合は、多かれ少なかれねじ込んだとあなたが何かのためにインデックスを格納する必要があるので。