- PR -

HashMapの値をソートして重複をなくす

1
投稿者投稿内容
Kira
ぬし
会議室デビュー日: 2004/10/30
投稿数: 252
投稿日時: 2004-10-30 10:30
はじめまして。
初歩的な質問かもしれませんが、以下のようなメソッドを作りたいと思ってます。
しかしどうしていいかわからないんで、サンプルのようなものはないでしょうか?

@引数はHashMap
A引数のハッシュマップをソート
B引数のハッシュマップの重複をなくす
Cハッシュマップをstring型で返す。
M-Falcon
会議室デビュー日: 2004/10/30
投稿数: 5
投稿日時: 2004-10-30 12:41
ども、私も初歩の人なので、チョット調べてみました。
# サンプルに心当りがないので...

2.はTreeMap + Comparatorなクラスを作成することで、SortedMapを生成して対応できそうです。
コード:
TreeMap treeMap = new TreeMap(comparator);
treeMap.putAll(hashMap);



3.これは素直にループで処理していいんじゃないでしょうか。
コード:
Itrator keyItrator = hashMap.keySet().itrator();
while(keyItrator.hasNext()){
 K key = keyItrator.next();
 V value = hashMap.get(key);
 if(null == value) continue; // nullなら次へ
 Itrator otherKeyItrator =  hashMap.keySet().itrator();
 while(otherKeyItrator.hasNext()){
  K otherKey = otherKeyItrator.next();
  if(otherKey.equal(key)) continue; //おなじKeyなら次へ
  V otherValue = hashMap.get(otherKey);
  if(otherValue.equal(value)) hashMap.remove(otherKey);
  // Key != otherKeyで value == othreValueなオブジェクトをエントリから削除
 }
}


# お、重そう

4....この質問だとどんなStringにしたいか不明ですが。

  • HashMap の toStringを使用する
  • HashMapをトラバースして、各要素を出力する(toString/format)

でしょうか。

これは普通にJDKのドキュメントを見ればいいかと

ちょっとは当っていればいいですが。
Odakaz
ベテラン
会議室デビュー日: 2004/05/24
投稿数: 70
投稿日時: 2004-10-30 14:00
3の処理は、キーの重複ではなくて、値の重複を取り除くという仕様でよろしいでしょうか?
#そもそもキーは重複しませんから。
であれば、TreeMapを拡張して値の重複を許さないコレクションを作ってしまうとか・・・。
というのは、2,3の処理で引数のマップは破壊されるので、ならば最初からそういうMapを作ってやればいいのかなと思いました。

文字列の出力は・・・どんな風に出力させたいかによってアプローチは変わりそうかな?

#ちょっと言葉が足りなかったので修正しました

[ メッセージ編集済み 編集者: Odakaz 編集日時 2004-10-30 14:10 ]

[ メッセージ編集済み 編集者: Odakaz 編集日時 2004-10-30 14:11 ]

[ メッセージ編集済み 編集者: Odakaz 編集日時 2004-10-30 14:13 ]
シュン
ぬし
会議室デビュー日: 2004/01/06
投稿数: 328
お住まい・勤務地: 東京都
投稿日時: 2004-10-30 14:11
例えば値が同一で異なるキーが2つ存在する場合に、片方のエントリを削除すると
いうことでしょうか?
そのとき、2つのキーのうちどちらを削除するのか?という判断を行う必要があり
ますので、put()するときにチェックするほうが楽ですね。

例えばこんな感じで。

コード:

public class MyMap extends HashMap{
//コンストラクタ省略
public void put(Object key,Object val){
if(!values().contains(val)){
 super.put(key,val);
}
}
}



>M-Falconさん
コレクションのイテレートの最中に対象コレクションの変更をおこなうと、ConcurrentModificationException例外が発生するかもしれません。
そういうコードは書かないほうがよいですよ。

[ メッセージ編集済み 編集者: シュン 編集日時 2004-10-30 14:16 ]
M-Falcon
会議室デビュー日: 2004/10/30
投稿数: 5
投稿日時: 2004-10-30 14:55
引用:

>M-Falconさん
コレクションのイテレートの最中に対象コレクションの変更をおこなうと、ConcurrentModificationException例外が発生するかもしれません。
そういうコードは書かないほうがよいですよ。


ああ、そうですね、ご指摘ありがとうございます。
ロックしたイテレータを取得するかマップのコピーを使うかしないとアレは駄目ですね。

いっそ、Old->Newで他の方も指摘しているような重複不可なMapを新規生成したほうが良いでしょうか。

# しばらくJavaから離れてた(wので
かつのり
ぬし
会議室デビュー日: 2004/03/18
投稿数: 2015
お住まい・勤務地: 札幌
投稿日時: 2004-10-31 00:59
>しかしどうしていいかわからないんで、サンプルのようなものはないでしょうか?

>@引数はHashMap
>A引数のハッシュマップをソート
>B引数のハッシュマップの重複をなくす
>Cハッシュマップをstring型で返す。

仕様がわからないので、回答する側もどうしていいかわからないと思いますよ。

Aどういうルールでソートするんですか?
 ・キーの昇順・降順 バリューの昇順・降順
 ・値の大小関係の判定基準
Bキーじゃなくてバリューの重複ですよね。どういう基準で値を重複とみなすんですか?
 ・value1.equals(value2)
 ・value1 == value2
 ・その他
CHashMapが引数でStringを返すということは、
 引数のHashMapに対しての変更は行わないという考えでいいですか?
 つまり引数のHashMapの中身から値を取り出して
 ソートして重複を取り除いたデータの文字列が欲しいという感じですかね?


ぶっちゃけこんな感じでOKですかね?
HashMap map = new HashMap();
map.put("aaa","bbb");
...
String values = new TreeSet(map.values()).toString();
1

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