web-dev-qa-db-ja.com

deleteCharAtまたはsetLength。StringBuilder/ StringBufferから最後の文字を削除する方が適切です。

多くの場合、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 ','
_

しかし、常にテーリング_','_を削除する必要があります。これを実装する方法は2つあります。

_sb.deleteCharAt(sb.length() - 1);
_

そして

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

どちらがお勧めですか?どうして?

注:_Arrays.toString_の機能は知っています。これは私の質問を説明するための単なる例であり、おそらく適切ではありません。 これは文字列の連結に関する説明ではなく、StringBuffer/StringBuilderのベストプラクティスです。

13
Weibo Li

実際、それはほとんどなく、おそらくハードウェアや他の要因に依存しています。

setLength()メソッドは、単純にカウントを変更し、配列内の不要な値をゼロバイトで上書きします。

deleteCharAt()は、カウントを変更する前に、内部的に配列コピーを実行します。これは劇的に聞こえますが、最後の文字を削除しているため、コピーされる配列は実際には長さがゼロです。

setLength()に行くことをお勧めします。タイプする方が短く、何をしているのかが明確になると思うパフォーマンスに問題があり、測定時にこれがボトルネックであることがわかった場合は、サイズを変更する必要のない別のアルゴリズムを検討することもできます(JB Nizetの回答によると)。

14

正しく行う方法は、コンマを条件付きで付加することです。

for (int i = 0; i < nums.length; i++) {
    if (i > 0)
        sb.append(',');
    sb.append(nums[i]);
}

その後、最後の文字はすでに正しいので、削除することを心配する必要はありません。

2
Bohemian

私はこのようにはしません。代わりに、要素が配列の最後の要素でない場合にのみ、末尾にコンマを追加します。または、Guavaのジョイナー(またはApache-commons StringUtils)を使用すると、より明確になります。

String s = Joiner.on(',').join(nums);

注意:Guavaのジョイナーはプリミティブ配列を処理しないことに気づきました。とにかく上からアイデアを得る必要があります。

1
JB Nizet