- PR -

コレクションフレームワーク(HashMap、ArrayList)

投稿者投稿内容
ume
会議室デビュー日: 2006/09/26
投稿数: 5
投稿日時: 2006-09-26 22:28
はじめまして、よろしくお願い致します。

現在、HashMapとArrayListを使って二次元のデータ処理をしたいと考えています。
環境的に、データベースを使えないため、JAVAのコレクションフレームワークのみで考えています。
プログラムが長いので、出力結果と質問を書かせていただきます。
プログラムでは、volumeとpriceはHashMapで格納し、そのデータをArrayListで格納しました。このデータのpriceを基準にsortしようと思ったのですが、できません。
また、[{volume=0, price=7}]を取り出すことはできるのですが、priceの7を取り出す方法がわかりません。

出力結果↓
orderAll=[[{volume=0, price=7}], [], [{volume=0, price=0}], [{volume=1,price=2}], [], [{volume=0, price=5}]]
nagise
ぬし
会議室デビュー日: 2006/05/19
投稿数: 1141
投稿日時: 2006-09-26 23:08
引用:

umeさんの書き込み (2006-09-26 22:28) より:
プログラムでは、volumeとpriceはHashMapで格納し、そのデータをArrayListで格納しました。このデータのpriceを基準にsortしようと思ったのですが、できません。



データ構造がイマイチわからないのですが…
DBの1レコードに相当するオブジェクトは何ですか?
そのオブジェクトをListに多数格納しているというイメージなのでしょうか。

List<Map<Integer, Integer>>型?そんな馬鹿な…。
List<Map<String, Integer>>あたりかなぁ…。
Mapのキーに"volume"とか"price"を渡すと値が取れるとか?

普通は1レコードに相当するオブジェクトを用意するものですよ。
そして、ソート処理は標準APIでできます。
ちょっとオブジェクトの使い方を覚える必要がありますが…

コード:
public class Record {
    public Record(int volume, int price) {
        this.volume = volume;
        this.price = price;
    }
    public int volume;
    public int price;
}

public class MyComparator implements Comparator<Record> {
    public int compare(Record o1, Record o2) {
        return o2.price - o1.price;
    }
}

public class Main {
    public static void main(String[] args){
        List<Record> list = new ArrayList<Record>();
        list.add(new Record(3, 5));
        ...

        java.util.Collections.<Record>sort(list, new MyComparator());
    }
}



参考
http://java.sun.com/j2se/1.5.0/ja/docs/ja/api/java/util/Collections.html
http://java.sun.com/j2se/1.5.0/ja/docs/ja/api/java/lang/Comparable.html
ume
会議室デビュー日: 2006/09/26
投稿数: 5
投稿日時: 2006-09-27 01:25
nagise様、ありがとうございます。

私の考え方と使い方が間違っているみたいです。
私が行った方法は、nagise様が推測するように
List<List<Map<String, Integer>>>を行いました。

目標にしている処理は、商品番号、価格、量のマッチング処理を考えています。
1レコードとしては、商品番号、価格、量となると思います。
nagise様のコードを実装してみました。
どのように格納したか出力するように下記をpublic class Main に追記しました。

System.out.println("List="+list);
Iterator all = list.iterator();
while (all.hasNext()){
System.out.println("all="+ all.next());
}


出力結果は下記のようになりました。
List=[e1.Record@addbf1, etmv1.Record@42e816, etmv1.Record@9304b1]
all=e1.Record@addbf1
all=e1.Record@42e816
all=e1.Record@9304b1

私が勉強不足かも知れませんが、入力した数字を表示することが出来ないでしょうか?。
list.add(new Record(3, 5));
list.add(new Record(1, 8));
list.add(new Record(6, 10));



[ メッセージ編集済み 編集者: ume 編集日時 2006-09-27 01:28 ]

[ メッセージ編集済み 編集者: ume 編集日時 2006-09-28 06:44 ]

[ メッセージ編集済み 編集者: ume 編集日時 2006-09-28 06:45 ]
ToGo
常連さん
会議室デビュー日: 2002/03/16
投稿数: 46
投稿日時: 2006-09-27 07:42
Recordクラスにpublic String toString()メソッドを実装(オーバーライド)すると
好みの表示を作れるようになります。
コード:
public class Record {
  :
  public String toString() {
    return "[volume=" + volume + ",price=" + price + "]";
  }
}


デバッグ(ロギング)用にtoStringメソッドをオーバーライドするのはよく行う方法ですので。
nagise
ぬし
会議室デビュー日: 2006/05/19
投稿数: 1141
投稿日時: 2006-09-27 09:06
引用:

umeさんの書き込み (2006-09-27 01:25) より:
私の考え方と使い方が間違っているみたいです。
私が行った方法は、nagise様が推測するように
List<List<Map<String, Integer>>>を行いました。

目標にしている処理は、商品番号、価格、量のマッチング処理を考えています。
1レコードとしては、商品番号、価格、量となると思います。



確かにMapでキーに項目名、Valueに値を置くことで
汎用的にどんな値でも入るようにはなるのですが、
DBのように1レコードに持つ情報を明確に定義するほうが
処理としてはやりやすいものです。

項目が可変であるような難しい要求でもない限り、
1レコード相当のデータ、つまり、Map<String, Integer>を
代替するようなクラスを作るのがオブジェクト指向としては自然でしょう。

デバッグ時の表示文字列はToGo氏の指摘どおりです。
toString()はjava.lang.Objectのメソッドですね。
vincent
大ベテラン
会議室デビュー日: 2004/07/09
投稿数: 142
投稿日時: 2006-09-27 09:35
Map<String, Object>をラップ(継承でもいいけど)して
テーブルにあわせたRowオブジェクトを作り、
各フィールド用のアクセサを用意するのがよいでしょう。

あと、Collection系クラスのtoString()で出力される
文字列のフォーマットを前提とした実装をするのは危険です。
(いつ仕様が変わるかわからないので)

決まった書式付きの行データを出力したければ、自前で
toString()をオーバーライドするか、別なメソッドを
用意すべきでしょう。
ume
会議室デビュー日: 2006/09/26
投稿数: 5
投稿日時: 2006-09-28 06:43
ToGo様、nagise様、vincent様ありがとうございます。

早速、Recordクラスにpublic String toString()メソッドを実装してみました。
表示され、ソートされている事を確認いたしました。

出力結果↓
List=[[volume=6,price=10], [volume=1,price=8], [volume=3,price=5]]
all=[volume=6,price=10]
all=[volume=1,price=8]
all=[volume=3,price=5]

この結果を用いて、別のListを作成して価格の一致処理を考えてみます。

vincent様からのアドバイスで、「テーブルにあわせたRowオブジェクトを作り、各フィールド用のアクセサを用意するのがよいでしょう。」とは、AccessibleRoleのROW_HEADERを使うことでしょうか。
初めて知る方法なので、こちらも勉強してみます。
Kazuki
ぬし
会議室デビュー日: 2004/10/13
投稿数: 298
投稿日時: 2006-09-28 07:07
引用:

umeさんの書き込み (2006-09-28 06:43) より:
vincent様からのアドバイスで、「テーブルにあわせたRowオブジェクトを作り、各フィールド用のアクセサを用意するのがよいでしょう。」とは、AccessibleRoleのROW_HEADERを使うことでしょうか。
初めて知る方法なので、こちらも勉強してみます。


get〜やset〜っていうメソッドのことです。

コード:

public class Person {
private String name; // フィールド

// アクセサメソッド
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
}



http://www.google.com/search?num=50&hl=ja&q=Java+%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B5&lr=lang_ja

[ メッセージ編集済み 編集者: Kazuki 編集日時 2006-09-28 11:11 ]

スキルアップ/キャリアアップ(JOB@IT)