プログラミングド素人のデザイナーがJava入門してみた_その8

## 前回までのあらすじ
[プログラミングド素人のデザイナーがJava入門してみた_その7](http://qiita.com/iwashi0830/items/6bdce3d72422ef2141b0)

## ジェネリクス
- 汎用化されたデータ型でクラスやインターフェースを作ることができる
- メソッドを呼び出すときに、引数のデータ型を選べるようにするということ
    - intしか受け付けない、Stringしか受け付けない、とかいう制約を取っ払える
    - 普通に書くと引数は決まった型でしか受け付けられないので、受けたい型の種類だけクラスを用意しないといけない
- ジェネリクスはクラスやインターフェース単位で指定する?
    - このクラスでは汎用データ型Tが使えますよ、と明示しておいて...
    - そのクラス内のメソッドの引数で汎用型Tを使う、という感じ?
- ジェネリクスをつかうと引数には**参照型しか使えなくなる**

```java

class Hoge <汎用の型名(Typeの頭文字Tとするのが慣習)>{//クラス宣言時に汎用のデータ型を扱うことを明示
  public void huga(T 引数){//引数の型は汎用型とする
    (引数が絡む)処理
  }
}

public class Piyo {

  public static void main(String[] args) {

    Hoge<使いたい型> i = new Hoge<>();//変数宣言時の型を<>で括り、インスタンス化する際クラス名の後に<>を付け足す
    i.huga(boo);//変数宣言時の型で引数を渡せる
  }
}
```

```java
class MyData <T>{//汎用データ型Tを用いる
  public void getThree(T x){引数xのデータ型は何でもOK
    System.out.println(x);//xを3度表示する
    System.out.println(x);
    System.out.println(x);
  }
}

public class HelloWorld {

  public static void main(String[] args) {

    MyData<Integer> i = new MyData<>();//変数iはInteger型として宣言&インスタンス格納
    i.getThree(10);//引数10はInteger型として渡される
  }

}
```

## スレッド処理
- スレッドとはコンピュータの処理単位のこと
- スレッドを複数立ち上げれば処理を並行して実行できる

### 1.処理内容の記述
- `Runnable`インターフェースを実装したクラスを作成
- ↑のクラスに`Runnable`インターフェースがもつ抽象メソッド`Run`を実装(オーバーライド)
- `Run`内に処理を書いていく

### 2.スレッド処理の実行
- 1.で作ったクラスのインスタンスを作成
- Threadクラスのインスタンスを作成し、コンストラクタの引数に↑のインスタンスを指定
- ↑のインスタンスがもつ`start()`メソッドを呼ぶことで実行

```java
class Huga implements Runnable { //Runnableインターフェースを実装したクラスを定義
  @Override //Runnableインターフェースがもつ抽象メソッドrunをオーバーライド
  public void run(){
    処理
  }
}

public class Hoge {

  public static void main(String[] args) {
    Huga huga = new Huga();//Runnableインターフェースを実装したクラスのインスタンスを作成
    Thread t = new Thread(r);//Threadクラスのインスタンスを作成し、引数として↑のインスタンスを渡す
    t.start();//↑のインスタンスがもつstart()で処理を実行

    for(int i = 0; i < 500; i++){
      System.out.print('.');
    }
  }

}
```

```java
class MyRunnable implements Runnable {
  @Override
  public void run(){
    for(int i = 0; i < 500; i++){
      System.out.print('*');
    }
  }
}

public class HelloWorld {

  public static void main(String[] args) {
    MyRunnable r = new MyRunnable();
    Thread t = new Thread(r);
    t.start(); //**********…

    for(int i = 0; i < 500; i++){
      System.out.print('.');//..........…
    }
  }

}
```

## Stringクラスを使う
- String型の変数の値をいろいろと扱う

|文字列の長さ|文字列を切り出す|文字列の置換|
|:---:|:---:|:---:|
|s.length()|s.substring(2,5)|s.replaceAll("置換対象","置換内容")|
|そのまんま(フィールドじゃなくメソッド)|2文字目から5文字目の*前*までを切り出す|そのまんま|

### 文字列内容の比較
 【`equals()`を使う方法】

```java
String s1 = "abc";
String s2 = "abc";

if(s1.equals(s2)){
  System.out.println("same");
}
```

【`==`を使う方法】

- 参照型の場合は**メモリ領域の場所**を比較
- Stringは参照型だが、異なる変数に同じ値が格納された場合は、同じメモリ領域を使うようになっている
- ので参照型だが比較すると真となる

```java
String s1 = "abc";
String s2 = "abc";//s1と同じ値なので同じメモリ領域を使いまわしている

if(s1 == s2){//真となりブロックの処理が実行される
  System.out.println("same same");
}
```

【異なるメモリ領域を使用することを明示するには】

- `new`することによってメモリ領域を独自に確保することを明示

```java
String ss1 = new String("abc");
String ss2 = new String("abc");//ss1と値は一緒だが、別のメモリ領域を確保

if(s1 == s2){//偽となりブロックの処理は実行されない
  System.out.println("same same");
}
```

## printfメソッド
- 指定した書式で文字列を表示できる
- `println`と違い改行されないので、必要に応じて`\n`を行末に追加

```java
String name = "tatou";
int age = 25;
double height = 165.5;
  //%xで表示する変数の型を指定して書式を記述
  //書式の後に、対応する型の順に変数名を記述することで、それぞれの値が格納される
  System.out.printf("name: %s age: %d height: %f \n", name, age, height);
```

|%s|%d|%f|
|:---:|:---:|:---:|
|文字列|整数値|浮動小数点|

### 表示桁数と行揃えの指定

- `%`に続けて数値指定で桁数を指定できる
- `-`をつけることで左詰めの指定が可能(`-`がない場合は右詰め)

```java
String name = "tatou";
    int age = 25;
    double height = 165.5;

    System.out.printf("name: %10s age: %-10d height: %5.2f \n", name, age, height);
```

|%10x|%-10x|%5.2f|
|:---:|:---:|:---:|
|10桁行事で右詰め|10桁表示で左詰め|整数部分５桁、小数点部分2桁で右詰め|

### 文字列として受け取る
- 単に出力するのではなく、文字列として変数に格納したい場合は`String`クラスの`format`メソッドを使う

```java
String name = "tatou";
int age = 25;
double height = 165.5;

  //String型の変数宣言と同時に、`format`メソッドで書式とはめ込む変数名を記述?
  String s = String.format("name: %10s age: %-10d height: %5.2f \n", name, age, height);
  System.out.println(s);
```

## 教科書
[ドットインストール](http://dotinstall.com/)さまさま

- [#33 ジェネリクスを使ってみよう](http://dotinstall.com/lessons/basic_java_v2/37733)
- [#34 スレッド処理を実装してみよう](http://dotinstall.com/lessons/basic_java_v2/37734)
- [#36 Stringクラスを使ってみよう](http://dotinstall.com/lessons/basic_java_v2/37736)

## [@iwashi0830](https://twitter.com/iwashi0830)はこう思った
- 無名クラス、ラムダ式はちょっと何言っているかわからなかったので後回し...
- 変数宣言と同時に、そのクラスが持っているメソッドを実行できる?
    - コンストラクタじゃないメソッドも呼べるのか?