Javaの学習 ~String~

### Stringクラス
java.lang.Stringクラスのこと。配列を内部に隠蔽しているため、文字列操作が可能なメソッドを提供することができます。

#### Stringクラスのインスタンス生成

```java
String a = new String("こんにちは");   //newを使う

String b = "こんばんは";   //newは省略できる

//☆文字列であるため、ダブルクォーテーション！
```
#### Stringオブジェクトは不変な（immutable）オブジェクト
オブジェクトに一度セットしたフィールドの値を、後から変更できるオブジェクトを「可変なオブジェクト」、変更できないオブジェクトを「不変なオブジェクト」と呼びます。
その「不変なオブジェクト」の代表例がStringオブジェクトです。

不変と聞くと全く中身を変えることができないように感じますが、
以下のコードで見てみると犬が猫に変わっていることが分かります。
```java
String str = "犬";
str = "猫";
System.out.println(str);

//実行結果
猫
```
一見、値が書き換えられたように思えますが、値そのものが書き換えられたのではありません。
参照型であるStringオブジェクトは、フィールドに別の値が代入されると、新たな別のアドレスを確保し、そのアドレスに対応する値に別の値を保管します。

このような事も起こりうるため、オブジェクトの内部データを変更できないように定義することがあります。
方法は次の４つです。
①全てのフィールドをprivateで修飾する
②setterメソッドなどの、内部データを変更できるメソッドを提供しない
③クラスをfinalで宣言し、オーバーライドを防ぐ
④getterメソッドなどを提供しない
```java
//例
public final class Sample {
    private final String name;
    public Sample(String name) {
        this.name = name;
    }
    public void dog() {
        System.out.println(name + "ちゃん");
    }
}
```

#### Stringクラスのメソッド
##### valueOfメソッド
valueOfメソッドを使うと、値をString型に変換することができます。
```java
//使用例
int a = 100;
String str = String.valueOf(a);
System.out.println(str);
```
##### toStringメソッド
`valueOfメソッド`と同様、値をString型に変換することができます。
```java
//使用例
int b = 200;
String str = Integer.toString(b);
System.out.println(str);
```
☆`valueOfメソッド`と`toStringメソッド`の違い
以下のような、変換する値が`null`の場合に、動作の違いが現れます。
```java
int c = null;
        
//valueOfの場合
String d = String.valueOf(c);
System.out.println(d);
//結果・・・String型のnullが返される
null
        
//toStringの場合
String e = Integer.toString(c);
System.out.println(e);
//結果・・・例外がスローされる（java.lang.NullPointerException）
```

##### replaceAllメソッド
replaceAllメソッドは、文字列を検索し、該当する部分を指定の文字列に置換する機能を持ちます。
※検索部分に正規表現を使用する事もある。正規表現を使用しない場合は、`All`を省いた後述する`replaceメソッド`を使う事もできるが、結局は内部処理で`replaceAll`を呼び出しているとのこと。
```java
String f = "hellocathello";
//replaceAll(検索する文字列, 置換する文字列);
f = f.replaceAll("hello", "bye");
System.out.println(f);

//結果
byecatbye
```

##### replaceメソッド
`replaceAll`同様、文字列を置き換えるためのメソッドです。
```java
String f = "aaaaa";
System.out.println(f.replace("aa", "b"));

//結果
bba
```
```java
String f = "aaaaa";
System.out.println(f.replace('a', 'b'));

//結果
bbbbb
```
指定した引数が存在しない場合は、元のままの文字列が返されます。
```java
String f = "aaaaa";
System.out.println(f.replace("zz", "b"));

//結果
aaaaa
```
以下のように、char型とCharSequence型が混在する場合、コンパイルエラーとなります。
```java
String f = "aaaaa";
System.out.println(f.replace("aa", 'b'));
```

##### charAtメソッド
このメソッドは、文字列の中から引数で指定した位置にある１文字を取り出します。
位置（順番）の数え方は配列と同じで、0,1,2,3・・・と0から順番に左から数えていきます。
※文字列が存在しない位置を引数として指定すると、java.lang.StringIndexOutOfBoundsExceptionの例外がスローされます。
```java
String g = "abcde";
System.out.println(g.charAt(2));

//abcde
//↓↓↓↓↓
//01234（順番）

//結果
c
```

##### indexOfメソッド
引数で指定された文字が、文字列のどの位置に存在するか調べてくれます。
これも、位置の数え方は配列と同じです。
```java
String h = "abcde";
System.out.println(h.indexOf('a'));
System.out.println(h.indexOf('z'));

//結果
//※同じの文字が複数ある場合は、最初に存在する位置を教えてくれる。
0
//指定の文字が存在しない場合は、-1を返す。
-1
```

##### substringメソッド
数字で引数を指定し、文字列から任意の文字列を取り出します。
取り出す際のイメージは以下の通りです。

| a | b | c | d | e |
「|」の左から順に0,1,2,3,4,5...と番号を振っていきます。

●引数を2つ指定
例えば、0と3を引数に指定すると、「abc」を抜き取ります。
1と5を引数に指定すると、「bcde」を抜き取ります。
```java
String i = "abcde";
System.out.println(i.substring(0, 3));
System.out.println(i.substring(1, 5));

//結果
abc
bcde
```

●引数を1つ指定
例えば、2を引数に指定すると、「|」の2番以降の文字列「cde」を抜き取ります。
```java
String j = "abcde";
System.out.println(j.substring(2));

//結果
cde
```

##### lengthメソッド
文字数を返すメソッドです。
半角英数字も全角文字も、どちらも１文字として扱われます。
```java
String k = "abcde";
System.out.println(k.length());

//結果
5
```
##### startsWithメソッド
文字列が指定の引数から始まるかを調べてくれます。結果は`true`、`false`の真偽値で返されます。
```java
String l = "hello";
System.out.println(l.startsWith("he"));

//結果
true
```
##### endsWithメソッド
文字列が指定の引数で終わっているかを調べてくれます。こちらも結果は真偽値で返されます。
```java
String m = "hello";
System.out.println(m.endsWith("o"));

//結果
true
```

### まとめ
最後まで閲覧いただきありがとうございました。どれもすごく便利なメソッドであると思いました。
ただ、全てのメソッドを網羅できたわけではないので、今後も新しいことを勉強していきたいです。
間違い等あれば、コメントお願いいたします。