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, он не равен пустой строке "".

Длинная версия

  1. Когда вы пытаетесь создать String с пустым char[10], выполните следующие действия:

    String input = new String(new char[10]);
    

    эта String будет содержать 10 символов NUL:

    |NUL|NUL|NUL|NUL|NUL|NUL|NUL|NUL|NUL|NUL|
    
  2. Когда вы вызываете input.replace("\0", "hello"), значение NUL (\0) будет заменено на hello:

    |hello|hello|hello|hello|hello|hello|hello|hello|hello|hello|
    
  3. Когда вы вызываете 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.

Если я попробую код в другой консоли, я получаю:

enter image description here

Подтверждая, что символы действительно не пробелы, а что-то другое (т.е. \0).

Ответ 4

Значение по умолчанию char - \u0000 которое также может быть представлено как \0. Итак, ваш new char[10] содержит 10 \0 с.

В первом утверждении вы явно замените \0 на "hello". Но во втором утверждении вы не учитываете значение по умолчанию. Какой выход IDE выберет для отображения в виде пробела.