- PR -

TreeMapについて

投稿者投稿内容
Edosson
ぬし
会議室デビュー日: 2004/04/30
投稿数: 675
投稿日時: 2005-06-29 11:45
ロジック上、間違ってる訳じゃないんですから、悪いってことはないと思います。
一応、必要なものだけを突き詰めるとどうなるか、ということで、参考までに。
コード:

int value1 = ((Comparable)((ArrayList)list1).get(0)).compareTo(((ArrayList)list2).get(0));
if (value1 != 0) {
return value1;
} else {
return ((Comparable)((ArrayList)list1).get(1)).compareTo(((ArrayList)list2).get(1));
}


こちらに関しては、もう納得されました?
引用:

なぜ正の整数や負の整数を返しただけで、並び替えられるのか?がよく分かりません。


要は比較の問題ですから、大きいか(正)、同じか(0)、小さいか(負)がわかればいいわけです。
人間が判定ロジックを定義すれば、ソートはTreeMapインスタンスが行います。

[ メッセージ編集済み 編集者: Edosson 編集日時 2005-06-29 11:51 ]
かつのり
ぬし
会議室デビュー日: 2004/03/18
投稿数: 2015
お住まい・勤務地: 札幌
投稿日時: 2005-06-29 12:37
日中は昼休みしかかけないのですが・・・もう解決しているみたいですね。
こういうパターンは定石として覚えると、後々に便利ですよ。

レコードがArrayListになっている時点で、あまりきれいではないといえます。
コード:
public class Record implements Comparable{

    private int age;
    private String name;
    private String memo;

    public int getAge(){return age;}
    public void setAge(int age){this.age = age;}
    ...以下同様にsetter/getter

    public int compareTo(Object obj){
        Record r = (Record)obj;
        int result = r.name.compareTo(name);
        if(result != 0){
            return result;
        }else{
            return r.age - age;
        }
    }
}


このように、Comparableを実装したJavaBeanの形式のレコードクラスを作成すると、
とてもすっきりすると思いますよ。Comparatorを作る必要がないですし。

Comparatorを作るときは通常、
・Comparableを実装していないオブジェクトで比較を行う
・実装済みの比較のアルゴリズムを取り替えたい
という感じで使用します。

では。
未記入
会議室デビュー日: 2005/06/28
投稿数: 11
投稿日時: 2005-06-29 13:29
スミマセン。少し私には難しくて、ついていけてない感じです。
クラスにして値を、今回ならば、都道府県コード、店コード、年月を持たし、
getter,setterを作り・・・
そして、このクラスは、
treeMap(new Record())のように入れたらいいのですか?
そしてこのクラスの値をキーにしたい場合はどうすればいいのですか?
map.put(???);


もう少し考えてみます。
難しいですねー。
かつのりさんのアドバイスは本当に勉強になります。
未記入
会議室デビュー日: 2005/06/28
投稿数: 11
投稿日時: 2005-06-29 13:52
なんとなく値の入れ方は分かってきました。
implement Comparableなのですか?
私は、implement Compareになってしまっているのですが、不味いですか?
comparableでは今出来ない状態になっています。
map.get(???)で今は迷ってしまっています。
値を取り出す時はどうすればいいのか?分からない状態です。
また形になり次第報告させていただきます。
かずくん
ぬし
会議室デビュー日: 2003/01/08
投稿数: 759
お住まい・勤務地: 太陽系第三惑星
投稿日時: 2005-06-29 16:42
引用:

implement Comparableなのですか?
私は、implement Compareになってしまっているのですが、不味いですか?


キーにするオブジェクトがComparableを実装している場合はComparable#compareTo()、
実装していない場合は、セットされたComparatorでの比較を試みます。
したがって、Comparatorをセットしていないのならキーにするクラスはimplement Comparableにしていないとダメです。

引用:

値を取り出す時はどうすればいいのか?分からない状態です。


new Record()でキーオブジェクトを作成し、TreeMap#get(キーオブジェクト)で値を取得します。
Gio
ぬし
会議室デビュー日: 2003/11/28
投稿数: 350
お住まい・勤務地: 都内から横浜の間に少量発生中
投稿日時: 2005-06-29 17:08
引用:

未記入さんの書き込み (2005-06-29 13:29) より:
そして、このクラスは、
treeMap(new Record())のように入れたらいいのですか?



Java のクラス群の命名規約によるのですが、比較に関しては
(1) Comparable
(2) Comparator
の二つがあります。慣れないと非常に紛らわしいと思うので、注意してください。

かつのりさんが書かれた Record クラスは (1) を使ったものです。
同じクラスの二つのオブジェクトを比較して整列する順序が明確に決まり、しかも比較方法自体を変更することがほとんどないという場合は、こちらの方がわかりやすいと思います。
この場合、TreeMap のコンストラクタは無引数のものを使います。

未記入さんが書かれて Edosson さんがフォローされた方法は (2) です。

詳しいことは API ドキュメントを読んでいただきたいのですが、
・コンストラクタ TreeMap(Comparator) で TreeMap を作った時は、put のキーには任意のオブジェクトを使って良い。
(ただし、Comparator オブジェクトが順序比較を責任持って実行すること。)
・無引数コンストラクタ TreeMap() の場合は、put のキーになるオブジェクトのクラスは Comparable を implement する必要がある。
ということです。

いずれの場合も、格納は
コード:

TreeMap map;
...
Record key = new Record();
Value val = new Value(); // key に関連付ける値

key.setAge(/* 年齢 */);
...
map.put(key, val);



取得は
コード:

Record anotherKey = new Record();
anotherKey.setAge(/* 年齢 */);
...
Value v = (Value) map.get(anotherKey);


のようになります。

[ メッセージ編集済み 編集者: Gio 編集日時 2005-06-29 17:19 ]
未記入
会議室デビュー日: 2005/06/28
投稿数: 11
投稿日時: 2005-06-29 17:36
あれからいろいろと作成したのですが、上手く動かない状態が続いています。

値を取り出す時に
================================================
//参考にしたクラス
public class Record implements java.util.Comparator {
private String Todou;
private String mise;
private String getudo;

public int compare(Object o1, Object o2) {
RecordSort r1 = (RecordSort)o1;
RecordSort r2 = (RecordSort)o2;
int result = r1.busyoNo.compareTo(r2.busyoNo);
if(result != 0){
return result;
}else{
return r1.seikyusakiNo.compareTo(r2.seikyusakiNo);
}
}
}
〜〜〜〜〜〜〜〜〜〜〜〜
//ここからmainで処理が始まる
Map map = new TreeMap(new Record());
Record r;
r = new Record();
r.setTodou("大阪");
r.setMise("002");
r.setGetudo("3");
map.put(r,"1000");

r = new Record();
r.setTodou("東京");
r.setMise("002");
r.setGetudo("4");
map.put(r,"2000");

r.setTodou("大阪");
r.setMise("002");
r.setGetudo("3");
System.out.println(map.get(r));
================================================
このような感じで書くと、
1000を出力してほしいにも関わらず、2000が表示されてしまいます。
これはどうしてなのでしょうか?
未記入
会議室デビュー日: 2005/06/28
投稿数: 11
投稿日時: 2005-06-29 17:39
投票する前にかずくんとGioさんの投稿を見逃していました。
今からすぐ読みます。
読まずに送信してしまいスミマセン。

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