s = s.substring(0, Math.min(s.length(), 10));
这样使用
Math.min字符串可以避免在字符串已经短于的情况下出现异常
10。
笔记:
上面做了真正的修剪。如果您实际上想将截断的最后三个(!)字符替换为点,请使用Apache Commons
StringUtils.abbreviate
。如果您的字符串包含BMP之外的Unipre代码点,则此行为可能不正确1。例如表情符号。有关适用于所有Unipre代码点的(更复杂的)解决方案,请参见解决方案。
像往常一样,没有人关心UTF-16代理对。请参阅以下内容:实际使用中最常见的非BMP Unipre字符是什么?甚至org.apache.commons / commons-lang3的作者
您可以在此示例中看到正确的代码和通常的代码之间的区别:
public static void main(String[] args) { //string with FACE WITH TEARS OF JOY symbol String s = "abcdafghiuD83DuDE02cdefg"; int maxWidth = 10; System.out.println(s); //do not care about UTF-16 surrogate pairs System.out.println(s.substring(0, Math.min(s.length(), maxWidth))); //correctly process UTF-16 surrogate pairs if(s.length()>maxWidth){ int correctedMaxWidth = (Character.isLowSurrogate(s.charAt(maxWidth)))&&maxWidth>0 ? maxWidth-1 : maxWidth; System.out.println(s.substring(0, Math.min(s.length(), correctedMaxWidth))); }}1-不在平面0(BMP)上的Unipre代码点在中表示为“代理对”(即两个
char值)
String。通过忽略这一点,我们可能会修剪到少于10个代码点,或者(更糟)在代理对中间截断。另一方面,
String.length()不再是Unipre文本长度的理想度量,因此基于它的修剪可能是错误的做法。



