sirve - ¿El toLowerCase() de Java conserva la longitud de la cadena original?
substring java (3)
En primer lugar, me gustaría señalar que estoy totalmente de acuerdo con la respuesta (actualmente con la calificación más alta) de @codaddict.
Pero quería hacer un experimento, así que aquí está:
No es una prueba formal, pero este código se ejecutó para mí sin llegar al interior del if
(usando JDK 1.6.0 Update 16 en Ubuntu):
Edición: Aquí hay un código actualizado que también maneja Locales:
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() + ")");
}
}
}
}
La ejecución de ese código con los nombres de la configuración regional mencionados en la respuesta aceptada imprimirá algunos ejemplos. Ejecutarlo sin un argumento probará todos los locales disponibles (¡y tomará bastante tiempo!).
No es extenso, porque teóricamente podría haber cadenas de caracteres múltiples que se comportan de manera diferente, pero es una buena primera aproximación.
También tenga en cuenta que muchas de las combinaciones de dos caracteres producidas de esta manera probablemente no sean válidas para UTF-16, por lo que el hecho de que nada explote en este código solo puede atribuirse a una API de cadena muy robusta en Java.
Y por último, pero no menos importante: incluso si la suposición es cierta para la implementación actual de Java, eso puede cambiar fácilmente una vez que las futuras versiones de Java implementen versiones futuras del estándar Unicode, en las que las reglas para los nuevos caracteres pueden introducir situaciones en las que esto ya no se mantiene cierto.
Así que dependiendo de esto sigue siendo una idea bastante mala.
Supongamos dos objetos de cadena Java:
String str = "<my string>";
String strLower = str.toLowerCase();
¿Es entonces cierto que para cada valor de <my string>
la expresión
str.length() == strLower.length()
evalúa a true
?
Entonces, ¿ String.toLowerCase()
conserva la longitud de cadena original para cualquier valor de String?
Sorprendentemente no lo hace !!
Desde documentos Java de toLowerCase
Convierte todos los caracteres en esta cadena a minúsculas usando las reglas de la configuración regional dada. La asignación de casos se basa en la versión estándar de Unicode especificada por la clase de caracteres. Dado que las asignaciones de casos no siempre son asignaciones de caracteres 1: 1, la Cadena resultante puede tener una longitud diferente a la Cadena original.
Ejemplo:
package com..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)
}
}
También recuerda que toUpperCase () tampoco conserva la longitud. Ejemplo: "straße" se convierte en "STRASSE" para el local alemán. Así que estás más o menos atornillado si trabajas con cadenas sensibles a las mayúsculas y necesitas almacenar el índice para algo.