Java Silver SE11 5章

# Java Silver SE11 5章
[黒本](https://www.amazon.co.jp/gp/product/4295007625/ref=ppx_yo_dt_b_asin_title_o00_s00?ie=UTF8&psc=1)をもとに学んだことをアウトプットしていきます。
主に問題を解いていて、間違えた箇所もしくは知らなかった内容になります。

## 配列
Javaの配列は、配列クラスから作成されたインスタンスであり、複数の値を取り扱う。
配列が扱う値のことを要素と呼ぶ。
以下のような特徴がある。

* 同じ型か互換性のある型を扱える
* インスタンス生成時に要素数を決める
  * 後から変更できない

### 宣言とインスタンス生成
宣言時には以下のルールがある。

* 記述する[]は、変数名の前後に入れることができる
* 宣言時に要素数の指定はできない
  * 配列型の変数には、あくまで配列インスタンスへの参照のみが代入されているので要素は関係ない

* 2次元配列を生成する場合の流れ(int[][]array = new int[2][2];)
  1. 1次元目の配列インスタンスを生成
  1. 2次元目の配列インスタンスを生成
  1. 1次元目の要素として、2次元目の配列インスタンスの参照が代入される

この時上記の内容から以下に注意する。

* 1次元目の要素数は省略できない
* 2次元目の配列インスタンスは後から生成できる
* 多次元配列でも変数に入っているのは、１次元目の参照のみ

例

```java:宣言
public class Array_declare {

	int[]array1 = new int[3];

	// []と変数名は逆でも問題なし
	int b[];

	// 2次元配列
	int[][]array2;

	// 3次元配列
	int array3[][][];

	// 分けて記述することも可能
	int[]array4[];
	int[][]array5[];

	// コンパイルエラー 要素数を指定する必要がある
	int[]array6 = new int[];

	// コンパイルエラー 要素数はint型 long型は×
	int[]array7 = new int[1.2];

	// 2次元配列のインスタンス生成
	int[][]array8 = new int[3][4];

	// 式を利用できる
	int c = 1; int d = 2;
	int[]array9 = new int[c * d];

	// 2次元目は後から生成できる
	int[][]array10 = new int[3][];
	// コンパイルエラー 1次元目は省略できない
	int[][]array11 = new int[][3];

	// コンパイルエラー 変数とインスタンスでの次元数は一致させる
	int[]array12 = new int[4][5];

	// コンパイルエラー 配列型変数の宣言時に要素数を指定できない
	int[2]array13;
}

```

### 要素のデフォルト値
要素のデフォルト値は以下のように決まっている。

| 型 | デフォルト値 |
|:-- |:-------- |
| 整数型 | 0  |
| 浮動小数点数型  | 0.0 |
| 真偽値  | false |
| 文字型  | ¥u0000 |
| Object型 | null |

例

```java:Itemクラス
public class Item {
	String name;
	int price = 100;
}
```

```java:デフォルト値
public class Array_element {

	public static void main(String[] args) {
		Item[]array = new Item[3];
		int total = 0;
		for(int i = 0; i < array.length; i++) {
			total += array[i].price;
		}
		System.out.println(total); 
		// × 300
		// nullPointerException をスローする
		// Itemインスタンスは生成されていないので、デフォルト値のnull
	}
}
```

### 初期化子 { }
配列インスタンスと要素の初期化を同時にする場合は、初期化子{}を使用する。
変数の宣言と同時にしか使用することができない。
(配列インスタンスを作成するときに、次元数を示せばOK)

```java:初期化
int[]array = {1, 2, 3};
```

### 宣言・生成・初期化 組み合わせ
以下に具体例を記載する。

```java:組み合わせ
public class Array_declare_format {

	public static void main(String[] args) {

		// 同じ意味
		int[]array1 = {1, 2, 3};
		int[]array2 = new int[] {1, 2, 3};

		// コンパイルエラー 初期化する場合、要素数を指定してはいけない
		int[]array3 = new int[3] {1, 2, 3};

		// 意味はないが、文法的に問題ない
		// 配列は複数の要素をまとめて扱うオブジェクトであり、要素そのものではない
		// 従って要素を持たない配列も作ることができる
		int[]array4 = {};
		int[]array5 = new int[0];

		// 2次元配列をまとめて初期化
		int[][]array6 = {{1, 2}, {3, 4, 5}};

		// コンパイルエラー 次元数が異なる 初期化をカウントしないように！
		int[][]array7 = new int[] {};
		// これならOK
		int[][]array8 = new int[][] {};

		// 分割して初期化できる 次元数を明示してるからOK
		int[]array9;
		array9 = new int[] {1, 2, 3};
		// コンパイルエラー 次元数を自動算出できない
		int[]array10;
		array10 = {1, 2, 3};
	}
}
```

### その他間違えた問題

```java:例題
public class Array_string {

	public static void main(String[] args) {
		String[]array = {"A", "B", "C"};
		array[0] = null;
		for(String str : array) {
			System.out.print(str); // nullBC
		}
		// nullはどこも参照していないことを表す「リテラル」である
		// なので、printで表示される
	}
}
```

```java:例題
public class Array_clone {

	public static void main(String[] args) {
		int[][]array1 = {{1, 2}, {1, 2},{1, 2, 3}};
		int[][]array2 = array1.clone();
		int total = 0;

		for (int[] array3 : array2) {
			for(int i : array3) {
				total += i;
			}
		}
		System.out.println(total); // 12
		System.out.println(array1 == array2); // false
	}
	// clone()は内容が全く同じ、別のインスタンスを生成する
	// したがって参照先はクローン元と一致しない
}
```