Как разбить строку с разделителями-запятыми на массив пустых строк

Я хочу разделить ",,," на массив из 4 "" с помощью String.split()

Вот мой код:

String str = ",,,";     
String[] tokens = str.split(",");

Однако токены результата были пустым массивом: [], а не массив из 4 "" (["","","",""]), как я хотел.

Я тестировал немного изменить str:

String str = ",,,1";        
String[] tokens = str.split(",");

На этот раз токены результата были ["","","","1"]. Это близко к тому, что я хочу, но я действительно не хочу добавлять этот "1", прежде чем делать раскол.

В основном проблема заключается в том, что String.split() вернет пустой массив, если содержит только пустые элементы "".

Помогите решить проблему?

Ответ 1

Вам нужно использовать перегруженный метод String#split(regex, limit), который принимает предельный параметр.

String[] tokens = str.split(",", -1);

Из docs (внимание мое):

Предельный параметр управляет количеством применений шаблона и, следовательно, влияет на длину результирующего массива. Если предел n больше нуля, шаблон будет применен не более n - 1 раз, длина массива будет не больше n, а последний элемент массива будет содержать все входные данные за пределами последнего сопоставленного разделителя. Если n не является положительным, шаблон будет применяться столько раз, сколько возможно, и массив может иметь любую длину. Если n равно нулю, шаблон будет применяться столько раз, сколько возможно, массив может иметь любую длину, а конечные пустые строки будут отброшены.


Объяснение: Если вы не предоставляете предельный аргумент или не указываете "ноль" в качестве предела, split() отбрасывает завершающие пустые поля. Когда вы предоставляете аргумент положительного предела, он ограничивает количество полей этим конкретным лимитом. Но когда вы предоставляете отрицательный предел, метод split() допускает любое количество полей, а также не отбрасывает конечные пустые поля. Чтобы быть более понятным, посмотрите исходный код Pattern#split(regex, limit), который имеет этот фрагмент в конце (комментарии были добавлены мной и не присутствовали в фактическом исходном коде).

if (limit == 0) // When zero or no arg is given
    while (resultSize > 0 && matchList.get(resultSize-1).equals("")) // if trailing entries are blank
        resultSize--; // remove them out

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

public String[] split(String regex) {
    return split(regex, 0);
}

А также обратите внимание, что String#split(regex, limit) внутренне вызывает Pattern#split(regex, limit).