Ответ 1
Здесь ответ второй части вопроса. Если у вас есть IntStream
, вызванный вызовом string.chars()
, вы можете получить Stream<Character>
, выполнив кастинг на char
, а затем поместите результат, вызвав mapToObj
. Например, здесь, как превратить a String
в Set<Character>
:
Set<Character> set = string.chars()
.mapToObj(ch -> (char)ch)
.collect(Collectors.toSet());
Обратите внимание, что для t23 > важно, чтобы результат с коротким значением был Character
вместо Integer
.
Теперь большая проблема с обработкой данных char
или Character
заключается в том, что дополнительные символы представлены как суррогатные пары значений char
, поэтому любой алгоритм с сделками с индивидуальными значениями char
, вероятно, дополнительные символы.
(Может показаться, что дополнительные символы - это неясная функция Юникода, о которой нам не нужно беспокоиться, но, насколько я знаю, все эможи являются дополнительными символами.)
Рассмотрим следующий пример:
string.chars()
.filter(Character::isAlphabetic)
...
Это будет fail, если будет представлена строка, содержащая кодовую точку U + 1D400 (Математическая жирная столица A). Эта кодовая точка представляется в виде суррогатной пары в строке, и ни значение суррогатной пары не является буквенным символом. Чтобы получить правильный результат, вам нужно сделать это вместо:
string.codePoints()
.filter(Character::isAlphabetic)
...
Я рекомендую всегда использовать codePoints()
.
Теперь, учитывая IntStream
кодовых точек, как можно собрать его в строку? Ответ Sleiman Jneidi является разумным (+1), используя метод collect()
> .
Здесь альтернатива:
StringBuilder sb = ... ;
string.codePoints()
.filter(...)
.forEachOrdered(sb::appendCodePoint);
return sb.toString();
Это может быть немного более гибким, если у вас уже есть StringBuilder
, который вы используете для накопления строковых данных. Вам не нужно создавать новый StringBuilder
каждый раз, и вам не нужно впоследствии преобразовывать его в String
.