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さまさまですね。 */