この講義で学んだこと。
Genericsのあるクラス・インタフェースの定義では、
class クラス名< 型パラメータ >
class インタフェース名< 型パラメータ >
のように、名前の後に型パラメータを入れる。
メソッドのみにGenericsをつけるには、
< 型パラメータ > 型 メソッド名( パラメータ )
のようにメソッドの戻り型の前に型パラメータを入れて定義する。
Genericsのあるクラス・インタフェースを実際に使用する際には、型パラメータの部分に具体的なクラスあるいはインタフェースを入れる。例えばクラスのGenericsだと
クラス名< 具体的なクラスあるいはインタフェース >
の形で使用する。
型パラメータは複数個指定できる。たとえば2個の場合、定義では、名前の後に
< 型パラメータ1, 型パラメータ2 >
をつけ、使用の際には
クラス名< 具体的なクラスあるいはインタフェース1, 具体的なクラスあるいはインタフェース2 >
の形で指定する。
| コレクション | 説明 | インタフェース | クラス |
|---|---|---|---|
| リスト | データの集まり | List | ArrayList LinkedList 等 |
| マップ | キー・値のペアの集まり (キーは重複無し) | Map | HashMap TreeMap 等 |
| セット | 重複しないデータの集まり | Set | HashSet TreeSet 等 |
いずれのクラス、インタフェースも、どういう種類のデータの集まりなのかを < > で囲まれる型パラメータで指定する。ただし、マップの場合は <キーの型, 値の型> のように2つの型パラメータを指定する。
一般的には下記のように import して利用
import java.util.List; import java.util.ArrayList; import java.util.Map; import java.util.HashMap;
リストの使い方の一例
// String を入れるリストを実体を ArrayList として定義
List<String> fruits = new ArrayList<>();
fruits.add("いちご"); // リストに追加
fruits.add("みかん");
fruits.add("メロン");
// 拡張for構文で一個ずつ取り出して処理できる
for (String s : fruits)
System.out.println(s);
System.out.println("Java 8 以降");
// Java 8 以降なら、forEachメソッドとラムダ式を使って繰り返しを記述できる
fruits.forEach((fruit) -> {
System.out.println(fruit);
});
// メソッド参照を使えば、さらに簡潔に下のように記述できる
fruits.forEach(System.out::println);
マップの使い方の一例
// キーを String、値を Integer とするマップを実体を HashMap として定義
Map<String, Integer> fruitMap = new HashMap<>();
// Map<String, int> はダメ。int の代りにラッパークラスの Integer を使用
fruitMap.put("みかん", 300); // マップに追加
fruitMap.put("メロン", 500);
fruitMap.put("いちご", 400);
// 拡張for構文で一個ずつ取り出して処理できる
for (Map.Entry<String, Integer> fruit : fruitMap.entrySet()) {
System.out.println(fruit.getKey() + ": " + fruit.getValue() + "円");
}
System.out.println("Java 8 以降");
// Java 8 以降なら、forEachメソッドとラムダ式を使って繰り返しを記述できる
fruitMap.forEach((fruit, price) -> {
System.out.println(fruit + ": " + price + "円");
});
動物クラスと継承クラスを使った演習プログラムを、コレクションフレームワークを使って書き換え、一部機能を追加する。
元の演習のソースファイル AnimalGroup.java をコピーし、ファイル名を AnimalGroupL.java と変え、元の AnimalGroup クラスを AnimalGroupL と変え、以下の変更を行う。
まず、ソース先頭に以下の import を追加する。
import java.util.Collections; import java.util.List; import java.util.ArrayList;
次にクラス AnimalGroupL を、元の AnimalGroup クラスのコードをベースにして以下のように変更する。
/**
* 演習 : 動物クラスと継承クラス (List使用版).
* @author 学籍番号・氏名
*/
public class AnimalGroupL {
public static void main(String[] args) {
List<Animal> animals = List.of( // 要素を指定したリスト生成
new Lion("Simba"),
new Cat("Felix"),
new Dog("Muttley"),
new Lion("Leo"),
new Shellfish("Clam")
);
for (Animal a : animals) {
System.out.print(a.getName() + "(" + a.getType() + ") ");
}
System.out.println();
// 追加修正分
List<Animal> animals2 = new ArrayList<>(animals); // リストのコピー
Collections.shuffle(animals2);
for (Animal a : animals2) {
a.makeSounds();
}
}
}
ソースの残りの Animal クラス以降の部分は変更しない。
以上の変更で、animals 変数が、Animal インスタンスの配列から、Animal インスタンスを要素とする List に変更される。
また、追加機能として、animals リストをコピーして animals2 リストを作り、Collections クラスのstaticメソッドである shuffle メソッドを呼び出すことにより animals2 リストの要素の順番をランダムシャッフルした後で各動物を鳴かせている。
ランダムシャッフルすることにより、実行する度に異なる順番で動物が鳴くようになっている。
なお、上では 動物クラスと継承クラスを使った演習 を基に書き換えたが、動物インタフェースと各種実装クラスの演習 を基にした場合も同様に修正できる。その場合、animals 変数は インタフェース Animal を実装するオブジェクトを要素とする List となる。
mainメソッドの中は上に示したものから変更する必要がなく、容易に作成できるので、各自でやってみるとよい。