当你必须遍历一个集合并用分隔符将每个数据组成一个字符串时,你总是会在最后得到一个额外的分隔符,例如:

for (String serverId : serverIds) {
  sb.append(serverId);
   sb.append(",");
}

给出类似serverId_1 serverId_2 serverId_3

我想删除StringBuilder中的最后一个字符(不转换它,因为在这个循环之后我仍然需要它)。


当前回答

从Java 8开始,String类有一个静态方法连接。第一个参数是每对字符串之间的字符串,第二个参数是Iterable<CharSequence>(这两个都是接口,所以List< string >之类的东西可以工作。所以你可以这样做:

String.join(",", serverIds);

同样在Java 8中,您可以使用新的StringJoiner类,用于您想要在有完整的元素列表之前开始构造字符串的场景。

其他回答

if(sb.length() > 0){
    sb.deleteCharAt(sb.length() - 1);
}

另一个简单的解决方案是:

sb.setLength(sb.length() - 1);

一个更复杂的解决方案:

上述解决方案假设sb.length() > 0…也就是说,有一个“最后一个字符”要删除。如果你不能做这样的假设,和/或你不能处理异常,将随之而来的假设是不正确的,然后先检查StringBuilder的长度;如。

// Readable version
if (sb.length() > 0) {
   sb.setLength(sb.length() - 1);
}

or

// Concise but harder-to-read version of the above.
sb.setLength(Math.max(sb.length() - 1, 0));

为了避免前缀的reinit(影响性能),使用TextUtils.isEmpty:

            String prefix = "";
            for (String item : list) {
                sb.append(prefix);
                if (TextUtils.isEmpty(prefix))
                    prefix = ",";
                sb.append(item);
            }
StringBuilder sb = new StringBuilder();
sb.append("abcdef");
sb.deleteCharAt(sb.length() - 1);
assertEquals("abcde",sb.toString());
// true

在这种情况下,

sb.setLength(sb.length() - 1);

是可取的,因为它只是将最后一个值分配给'\0',而删除最后一个字符的System.arraycopy