StrUtil添加reverseByCodePoint方法(pr#4187@Github)

This commit is contained in:
Looly
2025-12-24 18:09:13 +08:00
parent 5642321884
commit 8f64dd7d3d
2 changed files with 57 additions and 0 deletions

View File

@@ -288,6 +288,36 @@ public class StrUtil extends CharSequenceUtil implements StrPool {
return new String(ArrayUtil.reverse(str.toCharArray()));
}
/**
* 反转字符串<br>
* 例如abcd =》dcba
* <p>
* 该方法按Unicode code point进行反转支持Unicode字符的正确反转
* 确保复杂字符不会被拆分,如表情符号等多字节字符
* </p>
* @param str 被反转的字符串
* @return 反转后的字符串如果输入为null则返回null
* @since 5.8.43
*/
public static String reverseByCodePoint(String str) {
if (null == str) {
return null;
}
//按Unicode code point方式进行反转处理
StringBuilder result = new StringBuilder();
for (int i = str.length(); i > 0; ) {
//获取指定位置前的code point
int codePoint = str.codePointBefore(i);
//根据code point的字符数量调整索引位置
i -= Character.charCount(codePoint);
//将code point追加到结果中
result.appendCodePoint(codePoint);
}
return result.toString();
}
// ------------------------------------------------------------------------ fill
/**

View File

@@ -27,6 +27,7 @@ import java.nio.charset.StandardCharsets;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
/**
* 字符串工具类单元测试
@@ -683,4 +684,30 @@ public class StrUtilTest {
// 再次调用工具类转换,输出结果应该不变
assertEquals(originalText, StrUtil.str(buffer, StandardCharsets.UTF_8));
}
/**
* 测试字符串反转功能,特别是对特殊字符的处理
* 验证普通字符、中文字符以及Unicode代理对字符的反转行为
*/
@Test
public void reverseByCodePointSpecialCharactersTest() {
//普通情况-英文字符
assertEquals("dcba", StrUtil.reverseByCodePoint("abcd"));
//普通情况-中文字符
assertEquals("界世好你", StrUtil.reverseByCodePoint("你好世界"));
//保证Unicode字符语义正确类似emoji、组合字符
//A😊B
String emojiStr = "A\uD83D\uDE0AB";
String reversedEmoji = StrUtil.reverseByCodePoint(emojiStr);
//B😊A
assertEquals("B\uD83D\uDE0AA", reversedEmoji);
//A🇨🇳B
String surrogate = "A\uD83C\uDDE8\uD83C\uDDF3B";
String reversedSurrogate = StrUtil.reverseByCodePoint(surrogate);
//B🇨🇳A
assertNotEquals("B\uD83C\uDDE8\uD83C\uDDF3A", reversedSurrogate);
}
}