Pregunta

Supongamos que dos objetos String de Java:

String str = "<my string>";
String strLower = str.toLowerCase();

¿Es entonces cierto que para cada valor de la expresión <my string>

str.length() == strLower.length()

evalúa a true?

Por lo tanto, hace String.toLowerCase() preservar la longitud de la cadena original para cualquier valor de cadena?

¿Fue útil?

Solución

Sorprendentemente, se hace no !!

A partir de documentos de Java toLowerCase

  

Convierte todos los personajes de esta cadena a minúsculas utilizando las reglas de la configuración regional determinada. mapeo caso se basa en la versión estándar Unicode especificado por la clase de caracteres. Desde asignaciones de casos no siempre son 1: 1 asignaciones de carbón de leña, la cadena resultante puede ser una longitud diferente de la cadena original

.

Ejemplo:

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)
    }
}

Otros consejos

En primer lugar, me gustaría señalar que estoy totalmente de acuerdo con la respuesta (en la actualidad de mayor audiencia) de @codaddict.

Pero lo que quería hacer un experimento, así que aquí está:

No es una prueba formal, pero este código RAN para mí sin llegar nunca al interior de la if (utilizando JDK 1.6.0 actualización 16 en Ubuntu):

Editar Aquí hay un código actualizado que maneja Locales, así:

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() + ")");
            }
        }
    }
}

Correr ese código con los nombres específicos mencionados en la respuesta aceptada imprimirá algunos ejemplos. Ejecutarlo sin argumentos a tratar todos los locales disponibles (y tomar un buen tiempo!).

No es extensa, ya que en teoría podría ser 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 producidos de esta manera son UTF-16 probablemente no válida, por lo que el hecho de que explota Nada en este código sólo se puede culpar a una muy robusta API de cadena en Java.

Y por último pero no menos importante: incluso si el supuesto es cierto para la implementación actual de Java, que puede cambiar fácilmente una vez que las futuras versiones de Java aplicar las futuras versiones del estándar Unicode, en el que las reglas para nuevos caracteres pueden introducir situaciones donde esto ya no es válido.

Así que dependiendo de esto sigue siendo una muy mala idea.

También recuerde que toUpperCase () no conserva la longitud tampoco. Ejemplo: “Strasse” se convierte en “Strasse” para la configuración regional alemana. Lo que es más o menos atornillado, si está trabajando con cuerdas sensibles de casos y que necesita para almacenar el índice de algo.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top