A combining character modifies a preceding base character, so visible characters do not necessarily align with Java char values. Treating a string as char-by-char data can split a surrogate pair or separate a modifier from its base, producing broken output or altered appearance. section 6.1
The failure mode
A substring such as `string.substring(rowNumber * rowLength, (rowNumber + 1) * rowLength)` may cut an emoji or detach its skin-tone modifier. A waving-hand symbol with a dark skin tone occupies four Java chars: two surrogate pairs. Splitting after the hand can silently lose the requested tone. section 6.1
Avoid the mistake by choosing boundaries that match the operation:
- Use `codePoints()` with `StringBuilder.appendCodePoint` when chunks must preserve Unicode code points. section 6.1
- Use `BreakIterator.getCharacterInstance()` when boundaries should follow displayed character units rather than raw storage units. section 6.1
- Prefer `codePointAt(0)` over `charAt(0)` when testing the first Unicode code point. section 6.1
String part = string.codePoints().skip(rowNumber * rowLength)
.limit(rowLength)
.collect(StringBuilder::new,
StringBuilder::appendCodePoint,
StringBuilder::append)
.toString();
Inspect a code-point-based chunking implementation that preserves surrogate pairs. section 6.1
