コレクションフレームワーク
Set
Setは重複のないコレクション。すでに存在するものをadd()した場合は、falseが返される。
SetSample.java
import java.util.HashSet; import java.util.Set; public class SetSample { public static void main(String[] args) { Set<String> set = new HashSet<String>(); set.add("東京"); set.add("ロンドン"); set.add("パリ"); for (String item : set) { System.out.println(item); } } }
SetSample2は、SetインタフェースをCollectionインタフェースに置き換えただけ。
JavaDocでCollectionインタフェースを確認すると、ListやSetで使用したメソッドが定義されていることがわかる。
Eclipseの機能を使用してSetSample3.javaを作成する。
- SetSample.javaの上で右クリックしコピーを選択
- デフォルトパッケージの上で右クリックし貼り付けを選択
- クラス名が CopyOfSetSample になっているので、これを SetSample3 に修正してOKする
- これでSetSampleの内容がSetSample3.javaにコピーされる
SetSample.javaと異なる部分を入力してSetSample3.javaを作成する。
import java.util.HashSet; import java.util.Set; public class SetSample3 { public static void main(String[] args) { Set<String> set = new HashSet<String>(); set.add("東京"); set.add("ロンドン"); set.add("パリ"); if (!set.add("ロンドン")) { System.out.println("ロンドンは追加できない"); } if (set.contains("ロンドン")) { System.out.println("ロンドンはある"); } for (String item : set) { System.out.println(item); } } }
テキストにはない例題をやってみる。
- ListSample6.javaのmainメソッド内をコピーする
- SetSample6.javaのmainメソッドに貼り付ける
- ListをSetに変更する
- ArrayListをHashMapに変更する
- 変数listにカーソルを置きメニューのリファクタリングを選択
- 変数名listをset変更すると、すべてのlistがsetに変更される(便利!)
SetSample4.java
import java.util.HashSet; import java.util.Set; public class SetSample4 { public static void main(String[] args) { Set<Man> set = new HashSet<Man>(); set.add(new Man("孫", 10)); set.add(new Man("北尾", 15)); set.add(new Man("三木谷", 20)); if (!set.add(new Man("孫", 10))) { System.out.println("孫は追加できない"); } for (Man man : set) { System.out.println(man); } } }
これを実行すると、二人目の孫が追加できてしまう。
二人目の孫を追加できないようにコードを修正する。
Man.javaを修正する。
- Man.javaを開く
- メニューの ソース を選択する
- hashCode()およびequeals()の生成 を選択する
- ageとnameにチェックが入った状態でOKする
これで、Man.java にhashCode()とequals()のオーバーライドが生成される。
Man.java
public class Man { String name; int age; Man(String name, int age) { this.name = name; this.age = age; } void introduce() { System.out.println("僕は" + name + " 年は" + age); } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + age; result = prime * result + ((name == null) ? 0 : name.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Man other = (Man) obj; if (age != other.age) return false; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; return true; } @Override public String toString() { return super.toString() + "[name=" + name + ", age=" + age + "]"; } }
SetSample4.java を実行すると「孫は追加できない」と表示されるようになる。
Mapの利用
Mapはキーに対応した値を持つ集合。
MapSample.java
import java.util.HashMap; import java.util.Map; public class MapSample { public static void main(String[] args) { Map<String, String> map = new HashMap<String, String>(); map.put("red", "赤"); map.put("blue", "青"); map.put("yellow", "黄色"); String value = map.get("blue"); System.out.println(value); } }
要素を一覧する
MapSample2を作るまでもないので、MapSample.javaを修正して試す。
import java.util.HashMap; import java.util.Map; public class MapSample { public static void main(String[] args) { Map<String, String> map = new HashMap<String, String>(); map.put("red", "赤"); map.put("blue", "青"); map.put("yellow", "黄色"); //String value = map.get("blue"); //System.out.println(value); for (String key : map.keySet()) { String value = map.get(key); System.out.println(key + "=" + value); } } }
Iteratorを使った走査
Iteratorインタフェースを使って要素の走査をすることもできる。
IteratorSample.java
import java.util.ArrayList; import java.util.Iterator; import java.util.List; public class IteratorSample { public static void main(String[] args) { List<String> list = new ArrayList<String>(); list.add("東京"); list.add("ロンドン"); list.add("パリ"); Iterator<String> iter = list.iterator(); while (iter.hasNext()) { String item = iter.next(); System.out.println(item); } } }
配列とListの変換
配列からListへの変換はArraysクラスのstaticメソッドasList()を使用する。
Listから配列への変換はListインタフェースのtoArray()メソッドを使用する。
ArraySample.java
import java.util.Arrays; import java.util.List; public class ArraySample { public static void main(String[] args) { String[] array = new String[] {"東京", "ロンドン", "パリ"}; // 配列→リスト List<String> list = Arrays.asList(array); System.out.println("list"); for (String s : list) { System.out.println(s); } // List→配列 String[] array2 = list.toArray(new String[0]); System.out.println("array"); for (String s : array2) { System.out.println(s); } } }
ソートとComparator
Collectionsクラスのsort()メソッドを使って文字列をソートする例。
SortSample.java
import java.util.ArrayList; import java.util.Collections; import java.util.List; public class SortSample { public static void main(String[] args) { List<String> list = new ArrayList<String>(); list.add("いいい"); list.add("ううう"); list.add("あああ"); Collections.sort(list); for (int i = 0; i < list.size(); i++) { String item = list.get(i); System.out.println(i + ":" + item); } } }
ソート順序をカスタマイズする
ソート順序をカスタマイズするには java.util.Comparator インタフェースを実装したクラスを作成し、sort()メソッドの第2引数に渡す。
SortSample2.java
import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; public class SortSample2 { public static void main(String[] args) { List<String> list = new ArrayList<String>(); list.add("いい"); list.add("う"); list.add("あああ"); class MyComparator implements Comparator<String> { @Override public int compare(String o1, String o2) { return o1.length() - o2.length(); } } Collections.sort(list, new MyComparator()); for (int i = 0; i < list.size(); i++) { String item = list.get(i); System.out.println(i + ":" + item); } } }
無名クラスを使ったコードを追加する。
24行目で新しい要素を追加。
25~30行は、Collections.sort()メソッドの呼び出しで無名クラスのComparatorを第2引数に渡した例。
31~34行で結果の出力。
SortSample2.java
import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; public class SortSample2 { public static void main(String[] args) { List<String> list = new ArrayList<String>(); list.add("いい"); list.add("う"); list.add("あああ"); class MyComparator implements Comparator<String> { @Override public int compare(String o1, String o2) { return o1.length() - o2.length(); } } Collections.sort(list, new MyComparator()); for (int i = 0; i < list.size(); i++) { String item = list.get(i); System.out.println(i + ":" + item); } list.add("ええ"); Collections.sort(list, new Comparator<String>() { @Override public int compare(String o1, String o2) { return o1.length() - o2.length(); } }); for (int i = 0; i < list.size(); i++) { String item = list.get(i); System.out.println(i + ":" + item); } } }
引数が1個のsort()メソッドに渡すListは、Comparableインタフェースを実装しているクラスを格納しておかなければいけない。
Comparableインタフェースを実装していないManを格納したListを渡すコードを書いてみる。
SortSample2.java
import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; public class SortSample2 { public static void main(String[] args) { List<String> list = new ArrayList<String>(); list.add("いい"); list.add("う"); list.add("あああ"); class MyComparator implements Comparator<String> { @Override public int compare(String o1, String o2) { return o1.length() - o2.length(); } } Collections.sort(list, new MyComparator()); for (int i = 0; i < list.size(); i++) { String item = list.get(i); System.out.println(i + ":" + item); } list.add("ええ"); Collections.sort(list, new Comparator<String>() { @Override public int compare(String o1, String o2) { return o1.length() - o2.length(); } }); for (int i = 0; i < list.size(); i++) { String item = list.get(i); System.out.println(i + ":" + item); } List<Man> list2 = new ArrayList<Man>(); Collections.sort(list2); } }
Collections.sort(list2);の部分でコンパイルエラーになる。
Manクラスをimplements Comparable
Man.java
public class Man implements Comparable<Man>{ String name; int age; Man(String name, int age) { this.name = name; this.age = age; } void introduce() { System.out.println("僕は" + name + " 年は" + age); } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + age; result = prime * result + ((name == null) ? 0 : name.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Man other = (Man) obj; if (age != other.age) return false; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; return true; } @Override public String toString() { return super.toString() + "[name=" + name + ", age=" + age + "]"; } @Override public int compareTo(Man o) { return 0; } }