序論:コンテナ
他のクラスのオブジェクトを保存するものをコンテナ
(Container)と呼ぶ
集合、リスト、表
コンテナに求められる機能
追加、削除、参照
要素の比較
→並べ替え
要素のクラスが不明では、比較できない
要素が想定しているクラスのものかの判定
テンプレート以前の対応方法
コンテナ設計時に、保存されるクラスを特定してコンテ
ナをコードする
保存されるクラスごとに作成しなければならない
再利用可能性が下がる
最上位クラスのオブジェクトを保存するものとしてコード
する
想定外のオブジェクトを排除できない
大小関係を比較できない
比較するためのインターフェイスを実装したオブジェクト
を保存するものとしてコードする
想定外のオブジェクトを排除できない
J
AVA
5以前のコンテナ
private List list;
private SortedSet sortedSet;
list = Collections.synchronizedList(new ArrayList());
sortedSet = Collections.synchronizedSortedSet(new TreeSet());
/** sortedSetの中身をリストに変換 */
List sortedList = Collections.synchronizedList(new ArrayList());
while(!sortedSet.isEmpty()){
/** sortedSetから何が出てくるか不明なため、Objectのインスタンスになる */
Object first = sortedSet.first();
sortedSet.remove(first);
sortedList.add((Integer)first);
}
J
AVA
5以降のコンテナ:テンプレート使用
private List<Integer> list;
private SortedSet<Integer> sortedSet;
list = Collections.synchronizedList(new ArrayList<Integer>());
sortedSet = Collections.synchronizedSortedSet(new TreeSet<Integer>());
コンテナの要素となるクラスを指定
List<Integer> sortedList =
Collections.synchronizedList(new ArrayList<Integer>());
while(!sortedSet.isEmpty()){
/** sortedSetからInteger出てくるのが明か */
Integer first = sortedSet.first();
sortedSet.remove(first);
sortedList.add(first);
}
テンプレートを使用したコンテナの利点
コンパイル時に定義と要素の整合性を確認
取り出した要素を想定されるクラスにキャストする必要が
ない
テンプレートの活用:メソッド
public static <T extends Comparable<T>> void sort(T t[]) {
for (int i = t.length; i > 0; i--) {
for (int j = 0; j < i - 1; j++) {
if (t[j].compareTo(t[j + 1]) > 0) {
T c = t[j];
t[j] = t[j + 1];
t[j + 1] = c;
}
}
}
}
• ソートされるオブジェクトのクラスを特定せず、
Tと表記
• テンプレートクラス
TはインターフェイスComparableを実装
• メソッド
compareTo()を持つ
テンプレートの活用:クラス
public class BinaryHeap<T> {
/** データを保持するリスト */
private List<T> list;
/** 要素を比較する方法 */
private Comparator<T> comparator = null;
/** 要素数 */
Main.java
package withoutTemplate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.SortedSet;
import java.util.TreeSet;
/**
* テンプレートを使わない例 * @author tadaki
*/
public class Main { private List list;
private SortedSet sortedSet; public Main() {
/** thread-safeとするための処理 */
list = Collections.synchronizedList(new ArrayList());
sortedSet = Collections.synchronizedSortedSet(new TreeSet()); }
public void exec() { /** データの生成 */
for (int i = 0; i < 10; i++) {
int k = (int) (100 * Math.random()); list.add(k);
sortedSet.add(k); }
/** list の内容を出力 */
System.out.println("members in list"); for (int i = 0; i < list.size(); i++) { System.out.println(list.get(i)); }
/** sortedSetの中身をリストに変換 */
List sortedList = Collections.synchronizedList(new ArrayList()); while(!sortedSet.isEmpty()){
/** sortedSetから何が出てくるか不明なため、Objectのインスタンスになる */
Object first = sortedSet.first(); sortedSet.remove(first);
sortedList.add((Integer)first); }
/** sortedListの中身を出力 */
System.out.println("members in sortedSet"); for (int i = 0; i < sortedList.size(); i++) { System.out.println(sortedList.get(i)); }
}
/**
* @param args the command line arguments */
public static void main(String[] args) { 1/2 ページ
Main.java
new Main().exec(); }
}
Main.java
package withTemplate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.SortedSet;
import java.util.TreeSet;
/**
* テンプレートを使った例 * @author tadaki
*/
public class Main {
/** テンプレートでコンテナの要素のクラスを指定 */
private List<Integer> list;
private SortedSet<Integer> sortedSet; public Main() {
/** thread-safeとするための処理 */
list = Collections.synchronizedList(new ArrayList<Integer>());
sortedSet = Collections.synchronizedSortedSet(new TreeSet<Integer>()); }
public void exec() {
for (int i = 0; i < 10; i++) {
int k = (int) (100 * Math.random()); list.add(k);
sortedSet.add(k); }
System.out.println("members in list"); for (int i = 0; i < list.size(); i++) { System.out.println(list.get(i)); }
List<Integer> sortedList =
Collections.synchronizedList(new ArrayList<Integer>()); while(!sortedSet.isEmpty()){
/** sortedSetからInteger出てくるのが明か */
Integer first = sortedSet.first(); sortedSet.remove(first);
sortedList.add(first); }
System.out.println("members in sortedSet"); for (int i = 0; i < sortedList.size(); i++) { System.out.println(sortedList.get(i)); }
}
/**
* @param args the command line arguments */
public static void main(String[] args) { new Main().exec();
} }
Main2.java
package withTemplate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.SortedSet;
import java.util.TreeSet;
/** *
* @author tadaki */
public class Main2 {
/** 保存するデータの構造を定義 */
private class Data { private String label; private double value;
public Data(String label, double value) { this.label = label;
this.value = value; }
public String getLabel() { return label;
}
public double getValue() { return value;
} }
/** データの比較方法を定義 */
private class DataCompare implements Comparator<Data> { @Override
public int compare(Data o1, Data o2) { int k = 1; if (o2.value > o1.value) { k = -1; } if (o1.equals(o2)) { k = 0; } return k; } }
private SortedSet<Data> sortedSet; public Main2() {
sortedSet = Collections.synchronizedSortedSet( new TreeSet<>(new DataCompare())); 1/2 ページ
Main2.java
}
public void exec() {
for (int i = 0; i < 10; i++) { double d = 100 * Math.random();
sortedSet.add(new Data(String.valueOf(i), d)); }
List<Data> sortedList =
Collections.synchronizedList(new ArrayList<Data>()); while (!sortedSet.isEmpty()) {
/** sortedSetからInteger出てくるのが明か */
Data first = sortedSet.first(); sortedSet.remove(first);
sortedList.add(first); }
System.out.println("members in sortedSet"); for (int i = 0; i < sortedList.size(); i++) { Data d = sortedList.get(i);
System.out.println(
d.getLabel() + " " + String.valueOf(d.getValue())); }
}
/**
* @param args the command line arguments */
public static void main(String[] args) { new Main2().exec();
} }