7

現在、2 つの for ループを使用してすべてのエントリを比較していますが、比較が重複しています。HashMap は順序付けされていないため、既に行われた比較を削除する方法がわかりません。たとえば、次のようなものがあります。

    for(Entry<String, String> e1: map.entrySet())
    { 
        for(Entry<String, String> e2: map.entrySet())
        {    
          if (e1.getKey() != e2.getKey())
            {
           //compare e1.getValue() to e2.getValue() 
            }
        }
     }

これに関する問題は、最初のエントリが 2 番目のエントリと比較され、次に 3 番目のエントリと比較されるということです。ただし、2 番目のエントリは再び最初のエントリと比較されます。次に、3 番目のエントリが最初のエントリ、2 番目のエントリ、4 番目のエントリなどと比較されます。比較の重複を避けるために、HashMap を反復処理するより良い方法はありますか?

追加情報:

より具体的に、そしてできればあなたの質問に答えるために、私が持っている HashMap はファイル名 (キー) とファイルの内容 (値) を保存しています - テキストファイルだけです。HashMap は、比較対象のファイルを含むディレクトリをトラバースすることによって取り込まれています。次に、いくつかのアルゴリズムを使用してファイルのペアを実行し、各ファイルのペア間の類似性を判断しています。ファイル 1 をファイル 2 と比較し、次にファイル 2 をファイル 1 と比較する必要はありません。2 つのファイルを 1 回比較するだけでよいからです。ただし、すべてのファイルを他のすべてのファイルと一度比較する必要があります。私は HashMaps を扱うのは初めてです。以下のagimの答えは、私の目的にぴったりかもしれません。しかし、以下の Evgeniy Dorofeev と Peter Lawrey のソリューションの両方に頭を悩ませることも試みます。これが物事をよりよく説明するのに役立つことを願っています。

4

7 に答える 7

5

注意しないと、重複を排除するコストが、少なくともキーの冗長な比較のコストよりも高くなる可能性があります。

を使用してキーを注文できます。System.identityHashCode(x)

for(Map.Entry<Key, Value> entry1: map.entrySet()) {
   Key key1 = entry1.getKey();
   int hash1 = System.identityHashCode(key1);
   Value value1 = entry1.getValue();
   for(Map.Entry<Key, Value> entry2: map.entrySet()) {
       Key key2 = entry2.getKey();
       if (key1 > System.identityHashCode(key2)) continue;

       Value value2 = entry1.getValue();
       // compare value1 and value2;
   }
}
于 2013-01-07T09:23:32.270 に答える
4

このソリューションはどうですか?

String[] values = map.values().toArray(new String[map.size()]);
for (int i = 0; i < values.length; i++) {
  for (int j = i+1; j<values.length; j++) {
    if (values[i].equals(values[j])) {
      // ...
    }
  }
}
于 2013-01-07T03:19:23.230 に答える
1

試す

    HashMap<Object, Object> map = new HashMap<>();
    Iterator<Entry<Object, Object>> i = map.entrySet().iterator();
    while (i.hasNext()) {
        Entry next = i.next();
        i.remove();
        for (Entry e : map.entrySet()) {
            e.equals(next);
        }
    }

HashMap のキーを比較しても意味がないことに注意してください。それらは常に等しくありません。つまり、値のみを反復/比較できます

于 2013-01-07T03:05:08.290 に答える
0

私の理解が正しければ、マップの値に重複があるかどうか知りたいだけですか? もしそうなら:

Set<String> values = new HashSet<String>(map.values());
boolean hasDuplicates = values.size() != map.size();

最初の重複を見つけたら追い出すと、これはより効率的になる可能性があります。

Set<String> values = new HashSet<String>();
for (String value : map.values()) {
  if (!values.add(value)) {
    return true;
  }
}
return false;
于 2013-01-08T05:23:50.543 に答える
-1

結果の 2D 配列を使用してみることができます。結果がすでに入力されている場合は、再度比較を実行しないでください。これには、後で使用するために結果を保存できるという利点もあります。

したがって、int の結果の場合は、次のようになります。Integer[][] results = new Integer[map.entrySet().size()][map.entrySet().size()];これにより、配列が null に初期化され、比較の前に既存の結果を確認できるようになります。ここで注意すべき重要な点の 1 つは、それ自体との比較を除いて、各比較結果を配列に 2 回格納する必要があるということです。たとえば、インデックス 1 とインデックス 2 の比較は、 and に格納する必要がresults[1][2]ありresult[2][1]ます。

お役に立てれば。

于 2013-01-07T02:58:27.880 に答える