String replace() возвращает дополнительное пространство в Java
Рассматривать:
System.out.println(new String(new char[10]).replace("\0", "hello"));
имеет выход:
hellohellohellohellohellohellohellohellohellohello
но:
System.out.println(new String(new char[10]).replace("", "hello"));
имеет выход:
hello hello hello hello hello hello hello hello hello hello
Откуда эти дополнительные пространства?
Ответы
Ответ 1
Это не пространство. Так ваша IDE/консоль показывает символ \0
который по умолчанию заполняется new char[10]
символом new char[10]
.
Вы ничего не заменяете \0
, поэтому он остается в строке. Вместо этого с .replace("", "hello")
вы заменяете только пустую строку ""
. Важно то, что Java предполагает, что ""
существует":
- начало строки,
- конец строки,
- и между каждым из символов
так как мы можем получить "abc"
с:
"abc" = "" + "a" + "" + "b" + "" + "c" + ""';
//^ ^ ^ ^
Теперь .replace("", "hello")
заменяет каждый из этих ""
на "hello"
, поэтому для строки длиной 10 будет добавлено еще 11 hello
(не 10) без изменения \0
, которое будет показано на вашем выводить как пробелы.
Возможно, это будет легче понять:
System.out.println("aaa".replace("", "X"));
- позволяет представлять каждый
""
с помощью |
, Мы получим "|a|a|a|"
(заметим, что существует 4 |
) - так вместо
""
с X
приведет к "XaXaXaX"
(но в вашем случае вместо a
консоли будет печататься \0
, используя символ, который будет выглядеть как пространство)
Ответ 2
Укороченная версия
\0
представляет символ NUL
, он не равен пустой строке ""
.
Длинная версия
-
Когда вы пытаетесь создать String
с пустым char[10]
, выполните следующие действия:
String input = new String(new char[10]);
эта String
будет содержать 10 символов NUL
:
|NUL|NUL|NUL|NUL|NUL|NUL|NUL|NUL|NUL|NUL|
-
Когда вы вызываете input.replace("\0", "hello")
, значение NUL
(\0
) будет заменено на hello
:
|hello|hello|hello|hello|hello|hello|hello|hello|hello|hello|
-
Когда вы вызываете input.replace("", "hello")
, значение NUL
не будет заменено, так как оно не соответствует пустой строке ""
:
|hello|NUL|hello|NUL|hello|NUL|hello|NUL|hello|NUL|hello|NUL|hello|NUL|hello|NUL|hello|NUL|hello|NUL|hello|
Ответ 3
объяснение
Вы используете метод String#replace(CharSequence target, CharSequence replacement)
(документация).
Если вызывается с replace("", replacement)
пустой последовательности символов replace("", replacement)
она не будет заменять элементы в источнике, но вставлять замену перед каждым символом.
Это связано с тем, что ""
соответствует позициям между символами, а не самими символами. Поэтому каждая позиция между ними будет заменена, т.е. вставлена замена.
Пример:
"abc".replace("", "d") // Results in "dadbdcd"
Ваша строка содержит только значение по умолчанию char
в каждой позиции, это
\0\0\0\0\0\0\0\0\0\0
использование метода приводит к:
hello\0hello\0hello\0hello\0hello\0hello\0hello\0hello\0hello\0hello\0
дисплей
Ваша консоль, вероятно, отображает символ \0
как пробел, а на самом деле это не пробел, а \0
.
Если я попробую код в другой консоли, я получаю:
Подтверждая, что символы действительно не пробелы, а что-то другое (т.е. \0
).
Ответ 4
Значение по умолчанию char
- \u0000
которое также может быть представлено как \0
. Итак, ваш new char[10]
содержит 10 \0
с.
В первом утверждении вы явно замените \0
на "hello"
. Но во втором утверждении вы не учитываете значение по умолчанию. Какой выход IDE выберет для отображения в виде пробела.