classes - String replace() devuelve espacio extra en Java
stringbuilder java 8 api (4)
Considerar:
System.out.println(new String(new char[10]).replace("/0", "hello"));
tiene salida:
hellohellohellohellohellohellohellohellohellohello
pero:
System.out.println(new String(new char[10]).replace("", "hello"));
tiene salida:
hello hello hello hello hello hello hello hello hello hello
¿De dónde vienen estos espacios extra?
Explicación
Está utilizando el método String#replace(CharSequence target, CharSequence replacement)
( documentation ).
Si se invoca con una secuencia de caracteres de destino vacía, replace("", replacement)
no reemplazará los elementos en el origen, sino que insertará el reemplazo antes de cada carácter.
Esto se debe a que ""
coincide con las posiciones entre los caracteres, no con los propios caracteres. Así que cada posición entre será reemplazada, es decir, se insertará la sustitución .
Ejemplo:
"abc".replace("", "d") // Results in "dadbdcd"
Su cadena contiene solo el valor predeterminado de char
en cada posición, es
/0/0/0/0/0/0/0/0/0/0
el uso del método da como resultado:
hello/0hello/0hello/0hello/0hello/0hello/0hello/0hello/0hello/0hello/0
Monitor
Es probable que la consola muestre el carácter /0
como espacios en blanco , mientras que en realidad no es un espacio en blanco sino /0
.
Si pruebo su código en una consola diferente, obtengo:
Confirmando que los caracteres no son espacios sino algo diferente (es decir, /0
).
Version corta
/0
representa el carácter NUL
, no es igual a una cadena vacía ""
.
Versión larga
Cuando intenta crear una
String
con caracteres vacíoschar[10]
,String input = new String(new char[10]);
esta
String
contiene 10 caracteresNUL
:|NUL|NUL|NUL|NUL|NUL|NUL|NUL|NUL|NUL|NUL|
Cuando llame a
input.replace("/0", "hello")
, el valorNUL
(/0
) se reemplazará porhello
:|hello|hello|hello|hello|hello|hello|hello|hello|hello|hello|
Cuando llama a
input.replace("", "hello")
, el valorNUL
no se reemplazará ya que no coincide con la cadena vacía""
:|hello|NUL|hello|NUL|hello|NUL|hello|NUL|hello|NUL|hello|NUL|hello|NUL|hello|NUL|hello|NUL|hello|NUL|hello|
El valor predeterminado de char
es /u0000
que también se puede representar como /0
. Así que su new char[10]
contiene 10 /0
s.
En la primera declaración claramente reemplaza /0
con "hello"
. Pero en la segunda declaración dejas de lado el valor predeterminado. Que su salida IDE elige mostrar como un espacio.
No es un espacio. Así es como su IDE / consola muestra el carácter /0
que se llena el new char[10]
forma predeterminada.
No está reemplazando /0
con nada, por lo que permanece en cadena. En lugar de .replace("", "hello")
está reemplazando solo una cadena vacía ""
. Lo importante es que Java asume que ""
existe en:
- comienzo de la cadena,
- final de la cadena,
- y entre cada uno de los personajes.
ya que podemos obtener "abc"
con:
"abc" = "" + "a" + "" + "b" + "" + "c" + ""`;
//^ ^ ^ ^
Ahora .replace("", "hello")
reemplaza cada una de esas ""
con "hello"
, por lo que para la cadena de longitud 10 colocará 11 hello
adicionales (no 10 ), sin modificar /0
, que se mostrará en Tu salida como espacios.
Tal vez esto sea más fácil de entender:
System.out.println("aaa".replace("", "X"));
- vamos a representar cada
""
con como|
. Obtendremos"|a|a|a|"
(note que hay 4|
) - por lo tanto, reemplazar
""
conX
resultará en"XaXaXaX"
(pero en su caso, en lugar dea
consola, se imprimirá/0
usando un carácter que se verá como un espacio)