Java Silver SE11 3章

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

## インクリメント デクリメント
変数の値に１を加算、減算するための演算子。

```java:例
public class Main {
	public static void main(String[] args) {
		int a = 3;
		int b = a += 5; //1.a = a+5 2.b = a
		System.out.println(a); //8
		System.out.println(b); //8

		//コンパイルエラー intにlongを格納させようとしている
		int c = 2 * 3L; //エラー

		int d = 10;
		int e = d++ + d + d-- - d-- +  ++d; // 10 11 11 10 10
		System.out.println(e); //32

		int f = 10;
		int g = f++ + f; // 10 11
		System.out.println(g); //21
		int h = 10;
		int i = ++h + h; // 11 11
		System.out.println(i); // 22
	}
}
```

## 関係演算子
左右オペランドを比較し真偽値を戻す演算子のこと。


| 演算子 | 内容 |
|:-----|:---|
| a == b | aとbが等しければtrue |
| a !=b | aとbが等しくなければtrue |
| a > b | aがbより大きければtrue |
| a >= b | bがa以下であればtrue |
| a < b | bがaより大きければtrue |
| a <= b  | aがb以下であればtrue |
| a instanceof b  | aがbと同じクラスかbのサブクラスのインスタンスであればtrue |

## 理論演算子
複数の関係演算子を組み合わせて、条件を指定することができる。
「&&」と「&#124;&#124;」は、条件１(左オペランド)が「&であればfalse」「&#124;&#124;がtrue」であれば、
条件２(右オペランド)を確認(評価)しない。

| 演算子 | 内容 |
|:------|:-----|
| a & b | aとbの両方がtrueであればtrue　(aとb両方を評価する) |
| a && b | aとbの両方がtrueであればtrue (aがfalseであれば、b両方を評価しない) |
| a &#124; b | aもしくはbのいずれかがtrueであればtrue (aとb両方を評価する) |
| a &#124;&#124; b | aもしくはbのいずれかがtrueであればtrue (aがtrueであれば、bを評価しない)|
| !a | aがtrueであればfalse |

## 同一性 同値性
### 同一

* 複数の変数が同じインスタンスを参照していること
* ==演算子で判別する

### 同値
 
* インスタンスは異なるが同じ値をもっていること
* Objectクラスにあるequalsメソッドで判別する
  * equalsメソッドは、オーバーライドを前提としている
  * nullが引数として渡された時は、falseを返す

equalsメソッド
自分自身への参照を表すthisと、引数の参照を比較している。

```java:Objectクラスのequalsメソッド
public boolean equals(Object obj){
  return (this == obj);
}
```

```java:Sampleクラス
package chapter3_operator.Q10;

public class Sample {
	 private int num;

	public Sample(int num) {
		this.num = num;
	}

	public boolean equals(Sample obj) {
		if (obj == null) {
			return false;
		}
		return this.num == obj.num;
	}

	public Sample getThis() {
		return this;
	}
}
```

```java:Mainクラス
public class Main {
	public static void main(String[] args) {

		// Objectクラスで宣言
		Object a = new Sample(10);
		Object b = new Sample(10);
		// Sampleクラスで宣言
		Sample c = new Sample(10);
		Sample d = new Sample(10);

		System.out.println(a == b);      // false
		System.out.println(a.equals(b)); // false
		System.out.println(c == d);      // false
		System.out.println(c.equals(d)); // true
		System.out.println(c.getThis()); // Sample@7344699f
		System.out.println(d.getThis()); // Sample@6b95977
	}
}
```

```java:nullが渡された場合
public class Main {
	public static void main(String[] args) {
		Object a = new Object();
		Object b = null;
		System.out.println(a.equals(b)); // false
	}
}
```


### コンスタントプール
文字列リテラルは大量に登場するためメモリを大量に消費する。
そこで定数値として、インスタンスとは異なる定数用のメモリ空間に作成され、
そこへの参照が変数に格納される。

これにより同じ文字列リテラルが登場すると、参照が使い回されメモリ消費を軽減できる。
(文字列リテラルのみ有効で、new演算子を用いた場合は新しいインスタンスが作成され、それぞれの変数が異なる参照を持つ。)

```java:実際に検証
public class Main {
  public static void main(String[] args) {

    String st1 = new String("Sample");
    String st2 = st1;
    System.out.println(st1 == st2); //true
    System.out.println(st1.equals(st2)); //true
    System.out.println("=====");

    String st3 = new String("Sample");
    String st4 = new String("Sample");
    System.out.println(st3 == st4);  //false
    System.out.println(st3.equals(st4)); //true
    System.out.println("=====");

    String sample1 = "Sample";
    String sample2 = "Sample";
    System.out.println(sample1 == sample2); //true　コンスタントプールが影響
    System.out.println(sample1.equals(sample2)); //true
  }
}
```

## if文
* Javaではthenはない
* 下記３種類のif文で、{}は省略可能
 * 省略した場合は次の１文に対して、条件に合致した時の処理として実行される
* elseとifの間は改行はできない

```java:if文
if (条件){
  //条件に合致した時の処理
}

if (条件){
  //条件に合致した時の処理
} else {
  //条件に合致しなかった時の処理
}

if (条件A){
  //条件Aに合致した時の処理
} else if (条件B) {
  //条件Bに合致した時の処理
} else if (条件C)　 {
  //条件Cに合致した時の処理
} else {
  //全ての条件に一致しなかった時の処理
}
```
```java
public class Main {
	public static void main(String[] args) {
		int num = 10;
		// thenは使えない {}は省略可能
		if (num >= 10)
			System.out.println("OK"); //OK

		if (false)
			System.out.println("A"); //表示されない if文内にある
			System.out.println("B"); //Bは表示される if文とは無関係
	}
}
```

## switch文
* 条件式が戻せる型には制限がある
  * long、double、float、boolean型は使えない
* case値は以下の条件を満たす必要がある
  * 条件式が戻す値と同じ型か互換性がある型
  * final宣言された定数もしくは、リテラル、コンパイル時に値が決まるもの
  * nullでないこと
* breakを記載しない場合、以降の処理をbreakが現れるまで実行する
  * default式も実行される
* case式に何も記述しない場合、何もしないことになる
  * コンパイルエラーにはならない

```java:switch文
switch (条件式){
  case 値 : 処理
    break;
  case 値 : 処理
    break;
  default : 処理
    break;
}
```


## 2進数

2進数から１０進数に変換する時に、覚えておくと便利な表
| 128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 |
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
| 7乗  | 6乗  | 5乗  | 4乗  | 3乗  | 2の2乗  | 2の1乗  | 2の0乗 |

```:例
10進数１００を２進数で表すと？
100-64=36
36-32=4
答え： 1100100
```