Это, как правило, более безопасно использовать поток кодовых точек, который является IntStream
:
IntStream codePoints = string.codePoints();
Таким образом, Unicode пары суррогатных будут объединены в один элемент кода, так что вы будете иметь правильные результаты с любыми символами Unicode , Пример использования:
String result = string.codePoints().map(Character::toUpperCase)
.collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append)
.toString();
Также обратите внимание, что вам избежать бокс, таким образом, это может быть даже более эффективным, чем обработка Stream<Character>
.
Другой способ сбора такой поток должен использовать отдельный StringBuilder
:
StringBuilder sb = new StringBuilder();
String result = string.codePoints().map(Character::toUpperCase)
.forEachOrdered(sb::appendCodePoint);
Хотя такой подход выглядит менее функциональным, он может быть более эффективным, если у вас уже есть StringBuilder
или хотите объединить что-то более позднее к ту же строку.
Обратите внимание, что это решение не работает, если строка содержит символ Юникода, который не вписывается в Java-символ. Так обстоит дело, например, с некоторыми тайными языками, а также с смайликами. См. Ответ [Тагир] (https://stackoverflow.com/a/32472793/452775) для решений, которые обрабатывают это. – Lii