0Pricing
Java Academy · レッスン

StringBuilderとStringBuffer

スレッドセーフ性のトレードオフを学びます

「StringBuilderとStringBuffer」はCoddyKit上の無料Java Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはJava Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Java Academyコースには全4レッスンが含まれています。

2つの可変クラス

Java には可変な文字列クラスが2つあります。StringBuilder と StringBuffer です。API はほぼ同じですが、スレッドセーフという重要な点で異なります。

同じ API

どちらのクラスも append、insert、delete、reverse などを提供します。一方を使ったコードは、通常、型名を変更するだけでもう一方に切り替えられます。

public class Main {
    public static void main(String[] args) {
        StringBuffer sb = new StringBuffer();
        sb.append("Hello").append(", ").append("World");
        System.out.println(sb);
    }
}

StringBuffer は synchronized

StringBuffer のメソッドは同期化されています。つまり、複数のスレッドから同じインスタンスを安全に変更できます。その安全性には、わずかなパフォーマンス上のコストがあります。

public class Main {
    public static void main(String[] args) {
        StringBuffer buffer = new StringBuffer("thread-safe");
        buffer.append("!");
        System.out.println(buffer);
    }
}

StringBuilder は synchronized ではない

StringBuilder は同期化を行わないため、より高速です。その代わり、外部で調整せずに1つのインスタンスを複数のスレッド間で共有することは安全ではありません。

public class Main {
    public static void main(String[] args) {
        StringBuilder builder = new StringBuilder("fast");
        builder.append("!");
        System.out.println(builder);
    }
}

StringBuilder を使う場面

一般的なケースでは StringBuilder を使用します。たとえば、1つのメソッド内や単一のスレッド内で文字列を構築する場合です。日常的なコードでは、ほぼ常にこれが標準的な選択です。

public class Main {
    public static void main(String[] args) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 5; i++) {
            sb.append("#");
        }
        System.out.println(sb);
    }
}

StringBuffer を使う場面

同じビルダーのインスタンスを複数のスレッドが実際に共有して変更する場合に限り、StringBuffer を使用してください。実際には、このようなケースはまれです。

public class Main {
    public static void main(String[] args) {
        StringBuffer shared = new StringBuffer("log: ");
        shared.append("event A; ");
        shared.append("event B");
        System.out.println(shared);
    }
}

ローカル変数は共有されません

1つのメソッド内でのみ宣言および使用されるビルダーは、他のスレッドからは決して見えないため、その場合はStringBuilderを常に安全に使用できます。同期化されていなくても問題は起こりません。

public class Main {
    static String build() {
        StringBuilder sb = new StringBuilder();
        sb.append("local only");
        return sb.toString();
    }
    public static void main(String[] args) {
        System.out.println(build());
    }
}

パフォーマンスの違い

StringBufferの同期化によるオーバーヘッドのため、単一スレッドで使用すると遅くなります。処理量の多いループでは、StringBuilderのほうが高いパフォーマンスを発揮します。

public class Main {
    public static void main(String[] args) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 100000; i++) {
            sb.append('x');
        }
        System.out.println("Built length: " + sb.length());
    }
}

歴史に関する補足

StringBufferは初期のJavaで先に登場しました。StringBuilderはJava 5で、一般的な単一スレッドの場合に使える、同期化されていない高速な代替手段として追加されました。

正しく選択する

基本的にはStringBuilderを使用してください。1つのインスタンスが複数のスレッドで共有されていることを証明できる場合に限り、StringBufferに切り替えてください。そうでなければ、必要のない安全性のためにコストを支払うことになります。

public class Main {
    public static void main(String[] args) {
        StringBuilder result = new StringBuilder();
        result.append("Use StringBuilder ").append("by default");
        System.out.println(result);
    }
}

どちらもStringに変換されます

どちらのクラスも、toString()を通じて不変のStringを生成します。両者の選択は構築方法にのみ影響し、最終的な結果には影響しません。

public class Main {
    public static void main(String[] args) {
        String a = new StringBuilder("one").toString();
        String b = new StringBuffer("two").toString();
        System.out.println(a + " " + b);
    }
}

簡単な確認

StringBuilderとStringBufferの主な違いは何ですか。

まとめ

次のようなトレードオフについて学びました。

  • どちらもほぼ同一のAPIを備えています
  • StringBufferは同期化されています(スレッドセーフですが、低速です)
  • StringBuilderは同期化されていません(高速です)
  • 単一スレッドでの構築では、基本的にStringBuilderを使用します
  • 本当に共有されるインスタンスに限り、StringBufferを使用します

よくある質問

「StringBuilderとStringBuffer」レッスンは無料ですか?

はい。「StringBuilderとStringBuffer」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Java Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Java Academyコースには全4レッスンが含まれています。

「StringBuilderとStringBuffer」で何を学びますか?

スレッドセーフ性のトレードオフを学びます ブラウザで直接実行するハンズオンコードでJava Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Java Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのJava Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。

「StringBuilderとStringBuffer」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このJava Academyレッスンでコードを書いて実行できますか?

はい。すべてのJava Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. 文字列が不変である理由
  2. StringBuilderで文字列を構築する
  3. StringBuilderのメソッド
  4. StringBuilderとStringBuffer
← Java Academyに戻る