StringBuilderの各メソッドについて

今週末にJava Programmer Iの試験の予約を入れた。税込28,728円である。

kazmaarakaki.hatenablog.com

実はもう黒本については一通り終わっていて、今週中に間違えたところを重点的にもう一周するか、という感じだ。

8章以降のまとめもこのブログにしていきたいのだが、ノートが手元に無いのでとりあえず試験頻出のStringBuilderクラスについてまとめておきたいと思う。

コンストラクタ

返り値 引数
- なし 長さ16のint配列を内部に持つインスタンスを作成する
- int capacity 引数で指定した長さのint配列を内部に持つインスタンスを作成する
- String str 引数で指定した文字列の長さ + 16の長さのint配列を内部に持つインスタンスを作成する
- CharSequence seq 引数で指定したシーケンスの長さ + 16の長さのint配列を内部に持つインスタンスを作成する

append

返り値 引数
StringBuilder boolean b booleanの文字列表現をStringBuilderに追加
StringBuilder double d doubleの文字列表現をStringBuilderに追加
StringBuilder float f floatの文字列表現をStringBuilderに追加
StringBuilder int i intの文字列表現をStringBuilderに追加
StringBuilder long lng longの文字列表現をStringBuilderに追加
StringBuilder char c charの文字列表現をStringBuilderに追加
StringBuilder String str 文字列をStringBuilderに追加
StringBuilder char str char配列の文字列をStringBuilderに追加
StringBuilder Object obj Objectの文字列表現をStringBuilderに追加
StringBuilder StringBuffer sb StringBufferが持っている文字列をStringBuilderに追加
StringBuilder CharSequence s CharSequenceが持っている文字列をStringBuilderに追加
StringBuilder char str, int offset, int len char配列の文字列を部分的にStringBuilderに追加
StringBuilder CharSequence s, int start, int end CharSequenceが持っている文字列を部分的にStringBuilderに追加
public class Main {
  public static void main(String[] args) {
    CharSequence seq = "abcde";

    new StringBuilder().append(true); // => true
    new StringBuilder().append(0.1); // => 0.1
    new StringBuilder().append(0.1F); // => 0.1
    new StringBuilder().append(1); // => 1
    new StringBuilder().append(1L); // => 1
    new StringBuilder().append('a'); // => a
    new StringBuilder().append("abcde"); // => abcde
    new StringBuilder().append(new char[]{'a','b','c','d','e'}); // => abcde
    new StringBuilder().append(new Main()); // => Main@1db9742
    new StringBuilder().append(new StringBuffer("abcde")); // => abcde
    new StringBuilder().append(seq); // => abcde
    new StringBuilder().append(new char[]{'a','b','c','d','e'}, 1, 2); // => bc
    new StringBuilder().append(seq, 1, 2); // => b
  }
}
  • Objectを引数に取れるので、基本的に何を入れても実行できる。
  • 書いてないけどfloatも普通に引数に使える。
  • 部分的に追加するオーバーロードが2種類ある。第一引数にcharを入れるかCharSequenceを入れるかでその後の引数の意味が変わる。
    • charを入れた場合:第二引数で指定した文字から、第三引数で指定した長さを追加する。
      (abcdeのインデックス番号1の文字bから2文字分取得して追加する => ab)
    • CharSequenceを入れた場合:第二引数で指定したポインタから、第三引数で指定したポインタまでの文字を追加する。
      <0> a <1> b <2> c <3> d <4> e <5><1>から<2>の間の文字を取得して追加する => b)

appendCodePoint

返り値 引数
StringBuilder int codePoint Unicodeコードポイントの文字列表現を追加する
public class Main {
  public static void main(String[] args) {
    new StringBuilder().appendCodePoint(0x3042); // => あ
  }
}

capacity

返り値 引数
int - 現在の容量を返す

デフォルト

容量に初期化時の文字列の長さ + 16文字分のバッファを持っている。

public class Main {
  public static void main(String[] args) {
    new StringBuilder().capacity(); // => 16
    new StringBuilder("012").capacity(); // => 19
  }
}

appendされた時

容量内で文字列操作を行う。

public class Main {
  public static void main(String[] args) {
    new StringBuilder().capacity(); // => 16
    new StringBuilder().append("012").capacity(); // => 16
  }
}

長い文字列をappendして容量を超えた時

  • 17文字~34文字:バッファが34文字分に自動で拡張される。
  • 34文字~:バッファが文字列の長さと同じ容量に自動で拡張される
public class Main {
  public static void main(String[] args) {
    String str1 = "[20文字の文字列]";
    String str2 = "[40文字の文字列]";
    new StringBuilder().append(str1).capacity(); // => 34
    new StringBuilder().append(str2).capacity(); // => 40
  }
}

1文字ずつappendして容量を超えた時

(前レベルバッファ容量 + 1) * 2のバッファ容量が新しく設定される。

  • 1文字~16文字:バッファ容量 16
  • 17文字~34文字:バッファ容量 34
  • 35文字~70文字:バッファ容量 70
public class Main {
  public static void main(String[] args) {
    for(int i = 0; i < 100; i++) {
      StringBuilder sb = new StringBuilder();

      for(int j = 0; j < i; j++) {
        sb.append("aa");
      }

      System.out.println(
          sb.length() + ": " + sb.capacity()
      );
    }
  }
}
0: 16
2: 16
4: 16
6: 16
8: 16
10: 16
12: 16
14: 16
16: 16
18: 34
20: 34
22: 34
24: 34
26: 34
28: 34
30: 34
32: 34
34: 34
36: 70
38: 70
40: 70
42: 70
44: 70
46: 70
48: 70
50: 70
52: 70
54: 70
56: 70
58: 70
60: 70
62: 70
64: 70
66: 70
68: 70
70: 70
72: 142
74: 142
76: 142
78: 142
80: 142
82: 142
84: 142
86: 142
88: 142
90: 142
92: 142
94: 142
96: 142
98: 142
100: 142
102: 142
104: 142
106: 142
108: 142
110: 142
112: 142
114: 142
116: 142
118: 142
120: 142
122: 142
124: 142
126: 142
128: 142
130: 142
132: 142
134: 142
136: 142
138: 142
140: 142
142: 142
144: 286
146: 286
148: 286
150: 286
152: 286
154: 286
156: 286
158: 286
160: 286
162: 286
164: 286
166: 286
168: 286
170: 286
172: 286
174: 286
176: 286
178: 286
180: 286
182: 286
184: 286
186: 286
188: 286
190: 286
192: 286
194: 286
196: 286
198: 286

charAt

返り値 引数
char int index 指定されたインデックスのcharを返す
public class Main {
  public static void main(String[] args) {
    new StringBuilder("hello").charAt(1); // => e
  }
}

codePointAt

返り値 引数
int int index 指定されたインデックスの文字のコードポイントを返す
public class Main {
  public static void main(String[] args) {
    new StringBuilder("Hello").codePointAt(1); // => 101
  }
}

codePointBefore

何に使うのこれ。。。?

返り値 引数
int int index 指定されたインデックスの前の文字のコードポイントを返す
public class Main {
  public static void main(String[] args) {
    new StringBuilder("Hello").codePointBefore(2); // => 101
  }
}

codePointCount

返り値 引数
int int startIndex, int endIndex 指定された範囲ののコードポイントの数を返す
public class Main {
  public static void main(String[] args) {
    new StringBuilder("Hello").codePointCount(0, 3); // => 3
  }
}