JavaのStringについて

JavaのStringについてまとめます。

# Stringとは
文字列を扱うクラスです。結合を加算と同様の感覚で行えるため、C言語から移った人だと感動するかもしれません。

```Test.java
public class Test {
    public static void main(String[] args) {
        String a = "aaa";
        a += "bbb";
        a += "ccc";
        System.out.println(a);
    }
}
```

# Stringは不変オブジェクト
見た目上は結合を加算と同様に行えるStringですが、実は裏では __オブジェクトを作り直す__ という処理を行っています。これはStringが内容を変更できない __不変オブジェクト (イミュータブルなオブジェクト)__ の一種だからです。先ほどの例だと、次のような処理を行っていることになります。

```Test.java
public class Test {
    public static void main(String[] args) {
        String a = "aaa";
        a += "bbb"; // 『aaa』と『bbb』を結合させた文字列『aaabbb』を格納したStringを生成し、その参照をaに代入
        a += "ccc"; // 『aaabbb』と『ccc』を結合させた文字列『aaabbbccc』を格納したStringを生成し、その参照をaに代入
        System.out.println(a);
    }
}
```

# Stringの結合
## StringBuilder
### StringBuilder
StringBuilderは、`append`メソッドによって内部のchar配列に文字列を貯めていき、それらを結合させたStringを`toString`メソッドによって生成する、という形でStringを結合させるオブジェクトになります。
先ほど、Stringを結合させる際に裏ではStringを作り直している、と書きましたが、実はこのStringBuilderを用いて連結させているのです。例えば、先ほどのコードは実際には次のような処理を行っています。

```Test.java
public class Test {
    public static void main(String[] args) {
        String a = "aaa";
        a = (new StringBuilder(String.valueOf(a))).append("bbb").toString(); // 『aaa』と『bbb』を結合させた文字列『aaabbb』を格納したStringを生成し、その参照をaに代入
        a = (new StringBuilder(String.valueOf(a))).append("ccc").toString(); // 『aaabbb』と『ccc』を結合させた文字列『aaabbbccc』を格納したStringを生成し、その参照をaに代入
        System.out.println(a);
    }
}
```

このコードを見るとわかるように、結合させる度にStringBuilderが生成されています。しかし、貯めてから結合させるという使い方をするということを考えると、以下のような形にした方が効率が良いことがわかります。

```Test.java
public class Test {
    public static void main(String[] args) {
        StringBuilder sb = new StringBuilder();
        sb.append("aaa");
        sb.append("bbb");
        sb.append("ccc");
        String a = sb.toString();
        System.out.println(a);
    }
}
```

### StringBuffer
StringBuilderのスレッドセーフ版がStringBufferとなります。使い方はStringBuilderと同じです。

```Test.java
public class Test {
    public static void main(String[] args) {
        StringBuffer sb = new StringBuffer();
        sb.append("aaa");
        sb.append("bbb");
        sb.append("ccc");
        String a = sb.toString();
        System.out.println(a);
    }
}
```

## `concat`メソッド
Stringには2つのStringを結合させる`concat`メソッドというものがあり、次のように用います。


```Test.java
public class Test {
    public static void main(String[] args) {
        String a = "aaa";
        a = a.concat("bbb"); // 『aaa』と『bbb』を結合させた文字列『aaabbb』を格納したStringを生成し、その参照をaに代入
        a = a.concat("ccc"); // 『aaabbb』と『ccc』を結合させた文字列『aaabbbccc』を格納したStringを生成し、その参照をaに代入
        System.out.println(a);
    }
}
```
内部では2つの文字列を結合したStringを生成するという処理を行っています。

## 使い分け
多くの文字列を結合させるのであればStringBuilder (StringBuffer) を、一度文字列を結合させるだけであれば`concat`メソッドを用いるのが良いでしょう。

# 参考文献
* [スッキリわかるJava入門 実践編 第2版(中山 清喬・著)](http://www.amazon.co.jp/dp/4844336770/ref=pd_lpo_sbs_dp_ss_2?pf_rd_p=187205609&pf_rd_s=lpo-top-stripe&pf_rd_t=201&pf_rd_i=4844330861&pf_rd_m=AN1VRQENFRJN5&pf_rd_r=1PFQT5YXDT5MVT7M888W)
* [Javaにおけるオブジェクトの複製(clone) - 浅いコピーと深いコピー](http://education.yachinco.net/tips/java/05/note1.html)
* [参照についてもう少し詳しく ~PythonとJavaを例に~ - Qiita](http://qiita.com/ur_kinsk/items/7055ec8b50622289eeb2)
* [Stringの連結はそう簡単なものではない - じゅんいち☆かとうの技術日誌](http://d.hatena.ne.jp/j5ik2o/20110222/1298380551)