web-dev-qa-db-ja.com

StringBuilderの最後の文字を削除しますか?

コレクションをループ処理して各データのストリングを区切り文字で区切る必要がある場合は、常に末尾に余分な区切り文字を付けます。

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

serverId_1、serverId_2、serverId_3、のようになります。

StringBuilderの最後の文字を削除します(このループの後もまだ必要なので、変換しないでください)。

367
Matthew

他の人たちはdeleteCharAtメソッドを指摘しました、しかしここでもう一つの代替アプローチがあります:

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

あるいは、 Guava :)の Joiner クラスを使用します。

Java 8以降、 StringJoiner は標準のJREの一部です。

575
Jon Skeet

もう1つの簡単な解決策は、

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

もっと複雑な解決策:

上記の解決策は、sb.length() > 0 ...を削除する「最後の文字」があることを前提としています。その仮定ができない場合や、仮定が正しくない場合に発生する可能性がある例外を処理できない場合は、最初にStringBuilderの長さを確認してください。例えば.

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

または

// Concise but harder-to-read version of the above.
sb.setLength(Math.max(sb.length() - 1, 0));
375
Stephen C
sb.deleteCharAt(sb.length() - 1) 
156
bragboy

Java 8以降、Stringクラスは静的メソッド join を持ちます。最初の引数は文字列の各ペアの間に必要な文字列で、2番目の引数はIterable<CharSequence>(両方ともインターフェースなので、List<String>のようなものでも動作します。したがって、これを行うことができます。

String.join(",", serverIds);

また、Java 8では、要素の完全なリストを作成する前に文字列の構築を開始したいシナリオでは、新しい StringJoiner クラスを使用できます。それを入れてください。

56
ArtOfWarfare

この場合、

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

最後の値を'\0'に代入するだけなので、最後の文字を削除するとSystem.arraycopyになります。

33

最後の文字の出現位置を取得するだけです。

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

lastIndexOfは逆検索を実行するので、最初の試行で見つけられることがわかっているので、ここではパフォーマンスは問題になりません。

編集

私は自分の答えに追いついているので(ありがとうございました????)、それはそれに関して価値があります:

Java 8以降では、 StringJoiner を使用する方が読みやすく明示的になります。単純なセパレータのための1つのメソッドと、prefixとsuffixのためのオーバーロードがあります。

ここから取られた例: example

単純な区切り文字を使用した例:

    StringJoiner mystring = new StringJoiner("-");    

    // Joining multiple strings by using add() method  
    mystring.add("Logan");  
    mystring.add("Magneto");  
    mystring.add("Rogue");  
    mystring.add("Storm");  

    System.out.println(mystring);

出力:

ローガン - マグネット - ローグ - ストーム

サフィックスとプレフィックスを持つ例:

    StringJoiner mystring = new StringJoiner(",", "(", ")");    

    // Joining multiple strings by using add() method  
    mystring.add("Negan");  
    mystring.add("Rick");  
    mystring.add("Maggie");  
    mystring.add("Daryl");  

    System.out.println(mystring);

出力

(ネガン、リック、マギー、ダリル)

28
Reuel Ribeiro

Java-8ではStringクラスのstaticメソッドを使うことができます、

String#join(CharSequence delimiter,Iterable<? extends CharSequence> elements)


public class Test {

    public static void main(String[] args) {

        List<String> names = new ArrayList<>();
        names.add("James");
        names.add("Harry");
        names.add("Roy");
        System.out.println(String.join(",", names));
    }
}

OUTPUT

James,Harry,Roy
12
CoderCroc

他の選択肢

for(String serverId : serverIds) {
   sb.append(",");
   sb.append(serverId); 
}
sb.deleteCharAt(0);
10
Rafiq

あるいは

StringBuilder result = new StringBuilder();
for(String string : collection) {
    result.append(string);
    result.append(',');
}
return result.substring(0, result.length() - 1) ;
7
Zaki
StringBuilder sb = new StringBuilder();
sb.append("abcdef");
sb.deleteCharAt(sb.length() - 1);
assertEquals("abcde",sb.toString());
// true
5
Antoine

さらに別の方法:

public String join(Collection<String> collection, String seperator) {
    if (collection.isEmpty()) return "";

    Iterator<String> iter = collection.iterator();
    StringBuilder sb = new StringBuilder(iter.next());
    while (iter.hasNext()) {
        sb.append(seperator);
        sb.append(iter.next());
    }

    return sb.toString();
}
4
Jason Day

prefixの再起動(パフォーマンスへの影響)を回避するには、TextUtils.isEmptyを使用します。

            String prefix = "";
            for (String item : list) {
                sb.append(prefix);
                if (TextUtils.isEmpty(prefix))
                    prefix = ",";
                sb.append(item);
            }
3
NickUnuchek

あなたはあなたの生成されたテキストから最後の文字を削除する代わりに 'Joiner'クラスを使用しようとするかもしれません。

                List<String> textList = new ArrayList<>();
                textList.add("text1");
                textList.add("text2");
                textList.add("text3");

                Joiner joiner = Joiner.on(",").useForNull("null");
                String output = joiner.join(textList);

               //output : "text1,text2,text3"
1
oguzhan

私は以下のようなことをしています。

    StringBuilder stringBuilder = new StringBuilder();
    for (int i = 0; i < value.length; i++) {
        stringBuilder.append(values[i]);
        if (value.length-1) {
            stringBuilder.append(", ");
        }
    }
1
VicJordan

これは別の解決策です:

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

String resultingString = "";
if ( sb.length() > 1 ) {
    resultingString = sb.substring(1);
}
0
Stephan

私は個人的には末尾にバックスペース文字(もっと長い "delimiter"の場合はそれ以上)を追加するのが好きです。

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

sb.append('\b');

問題があることに注意してください。

  • \bの表示方法は環境によって異なります。
  • Stringコンテンツのlength()は、 "visibile"文字の長さとは異なる場合があります

\bが問題ないように見え、コンソールへのログインのように長さが問題にならない場合、これは私には十分に思えます。

0
Attacktive