![]() | Category | サンプルソース |
|---|---|---|
ファイルから読み込んだデータを、カテゴリーごとに分類。画面表示とデータ管理の分離は、プログラム設計の基本です。 |
Category.java ComicChar.java DataManager.java |
/**
* 愛のJava256本ノック for Java 5.0
* Javaサンプルソース ver0.2C "Category"
* Category.java 「Setを使ったカテゴリー分類」
*
* 2005/09/23 制作:安永ノリカズ
*
* 【コンパイル&実行方法】
* >javac *.java
* >java Category
* 【キーワード】
* クラス設計(class design), Model(処理), View(表示)
* 【試してみよう】
* CSVにデータを追加し、カテゴリーが増えるのを確認する。
* 編集した内容をCSVに書き出す「保存」機能をつける。
*
*/
import java.awt.BorderLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.lang.String;
import java.util.List;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JTextArea;
public class Category extends JFrame implements ActionListener {
JComboBox I00;
JTextArea I01;
DataManager I02;
public Category() {
I02 = new DataManager();
// カテゴリーのリストを取得して、コンボボックスを作成
I00 = new JComboBox(I02.M00());
I01 = new JTextArea();
add(I00, BorderLayout.NORTH);
add(I01, BorderLayout.CENTER);
I00.addActionListener(this);
}
public void actionPerformed(ActionEvent A00) {
String L00 = (String)I00.getSelectedItem();
// 選択されたカテゴリーに含まれるデータを検索
List<ComicChar> L01 = I02.M01(L00);
I01.setText("");
for (ComicChar L02 : L01) {
I01.append(L02.I01 + "\n");
}
}
public static void main(String[] A00) {
Toolkit.getDefaultToolkit().setDynamicLayout(true);
Category L00 = new Category();
L00.setTitle("カテゴリーごとに分類");
L00.setDefaultCloseOperation(EXIT_ON_CLOSE);
L00.setSize(320, 240);
L00.setVisible(true);
}
}
/* ■ クラスの外でちょっと一言 ■
CSVファイルからデータを読み込み、カテゴリーごとに分類して表示するプログ
ラムです。まずはプログラムを動かし、付属のCSVファイルの中身と見比べてく
ださい。
このサンプルは、Category、DataManager、ComicCharの3つのクラスで構成され
ており、それぞれで役割を分担しています。Categoryクラスは、GUIやイベント
処理などを担当。ComicCharは1件のデータを表すクラスで、そのComicCharのリ
ストをDataManagerクラスが管理する構造になってます。
クラス設計において、「画面表示」と「データ管理」を分けるのは基本中の基
本。クラス分けに悩む場合は、まずここを取っ掛かりにすればいいかと思いま
す。
*/
/**
* 愛のJava256本ノック for Java 5.0
* Javaサンプルソース ver0.2C "Category"
* ComicChar.java 「Setを使ったカテゴリー分類」
*
* 2005/09/23 制作:安永ノリカズ
*
* 【コンパイル&実行方法】
* >javac *.java
* >java Category
* 【キーワード】
* コンストラクタ(constructor)
* 【試してみよう】
* Category.javaを参照。
*/
import java.lang.String;
public class ComicChar {
String I00; // カテゴリー名
String I01; // キャラクター名
public ComicChar(String A00, String A01) {
this.I00 = A00;
this.I01 = A01;
}
}
/* ■ クラスの外でちょっと一言 ■
これは、単純にデータを管理するクラスです。comic_char.csvの形式が、
[カテゴリー名],[キャラクター名]
のようになってますので、それぞれのデータを格納するフィールドを用意してい
ます。CSVファイルの行数分、このクラスのインスタンスが生成されますので、
CSVファイルの中身を確認しておいてください。
それにしても『北斗の拳』は熱いぜ! 熱くて死ぬぜ!
*/
/**
* 愛のJava256本ノック for Java 5.0
* Javaサンプルソース ver0.2C "Category"
* DataManager.java 「Setを使ったカテゴリー分類」
*
* 2005/09/23 制作:安永ノリカズ
*
* 【コンパイル&実行方法】
* >javac *.java
* >java Category
* 【キーワード】
* ジェネリックス(generics), 拡張forループ, Set(集合), List(リスト),
* equalsによる文字列の比較
*
* 【試してみよう】
* Category.javaを参照。
*/
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.lang.String;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
public class DataManager {
static final String C00 = "comic_char.csv";
List<ComicChar> I00 = new ArrayList<ComicChar>();
public DataManager() {
// CSVファイルからデータを読み込んでリストに追加
try {
BufferedReader L00 = new BufferedReader(new FileReader(C00));
String L01;
while( (L01 = L00.readLine()) != null ) {
String[] L02 = L01.split(",");
I00.add(new ComicChar(L02[0], L02[1]));
}
L00.close();
} catch(FileNotFoundException L03) {
System.out.println(C00 + "が見つかりませでした。");
} catch(IOException L04) {
System.out.println(C00 + "を読み込めませんでした。");
}
}
// カテゴリーの配列を返す
public String[] M00() {
Set<String> L00 = new LinkedHashSet<String>();
for (ComicChar L01 : I00) {
L00.add(L01.I00);
}
return L00.toArray(new String[0]);
}
// カテゴリーを指定して検索
public List<ComicChar> M01(String A00) {
List<ComicChar> L00 = new ArrayList<ComicChar>();
for (ComicChar L01 : I00) {
if (L01.I00.equals(A00)) {
L00.add(L01);
}
}
return L00;
}
}
/* ■ クラスの外でちょっと一言 ■
データの管理を担当するこのクラスには3つの機能が備わってます。
まずは、コンストラクタで外部ファイルからデータを読み込む機能。読み込まれ
たデータは1件ごとインスタンス化されて、Listに追加されます。以降、この
Listから、随時必要なデータを取り出すことになります。コンストラクタなん
で、ファイルの読み込みは最初の1回だけですね。
次は、カテゴリーを集計する機能。読み込んだListから、カテゴリーを取り出し
てますが、ポイントは、重複を省く必要があるということ。そこでコレクション
フレームワークのSetの登場です。Setは、数学でいうところの「集合」で、重複
要素を持たないという性質があります。こういう集計にはぴったりですね。
Setから配列への変換にtoArrayメソッドを使ってますが、その引数にString[0]
と、長さ0の配列を渡してます。このメソッドは、「配列のサイズが十分でない
場合は、同じ実行時の型で新しい配列が格納用として割り当てられる」そうなの
で、配列の長さは0でOK。大事なのは配列の型だけです。
最後に、指定されたカテゴリーのデータだけを取り出す機能。元のListから該当
するデータを選んで、別のListに追加しています。「毎回新しいListを生成し
て、メモリは大丈夫か?」という気がしますが、Listにはインスタンスの参照が
入るだけなので、それほど資源は消費しません。
ジェネリックスのおかげで面倒な型変換がなく、拡張forループですっきりと全
要素の走査ができてます。このへんは、J2SE 5.0さまさまですね。
*/