在许多情况下,我们需要删除StringBuilder / StringBuffer的最后一个字符。例如,给定int[]{1,2,3}
,以实现String toString(int[] a)
方法,使用逗号分隔符联系每个元素。输出应该是1,2,3
,没有拖尾逗号。
我们可以轻松编写一个循环:
int[] nums = new int[]{1,2,3,4,5};
StringBuilder sb = new StringBuilder();
for (int i = 0; i < nums.length; i++) {
sb.append(nums[i]);
sb.append(",");
}
//here we need to remove the tailing ','
但我们总是需要删除尾部','
。有两种方法可以实现它:
sb.deleteCharAt(sb.length() - 1);
和
sb.setLength(sb.length() - 1);
推荐哪一个?为什么呢?
注意:
我知道Arrays.toString
做了什么。这只是一个描述我的问题的例子,可能不太合适。
这不是关于字符串连接的讨论,而是StringBuffer / StringBuilder的最佳实践。
答案 0 :(得分:14)
实际上,其中很少,可能依赖于硬件和其他因素。
setLength()
方法只是改变计数并用零字节覆盖数组中不需要的值。
deleteCharAt()
在更改计数之前在内部执行数组复制。这听起来很戏剧性,但被复制的数组实际上是零长度,因为你要删除最后一个字符。
我建议选择setLength()
,因为输入的时间更短,我认为更清楚你在做什么。如果性能是一个问题,并且在测量时,你发现这是你的瓶颈,那么也许你可以考虑一个不需要改变大小的不同算法(根据JB Nizet的答案)。
答案 1 :(得分:2)
如何正确地执行此操作是有条件地添加逗号:
for (int i = 0; i < nums.length; i++) {
if (i > 0)
sb.append(',');
sb.append(nums[i]);
}
然后你不必担心删除最后一个字符,因为它已经是正确的了。
答案 2 :(得分:1)
我不会这样做。相反,如果元素不是数组的最后一个元素,我只会添加一个尾随逗号。或者我会使用Guava的Joiner(或Apache-commons StringUtils),这使它更清晰:
String s = Joiner.on(',').join(nums);
注意:我刚注意到Guava的Joiner不处理原始数组。无论如何你应该从上面得到这个想法。