2

で重複する値を削除する良い方法を誰かが知っているかどうか疑問に思っていLinkedHashMapます ? LinkedHashMapと のペアStringを持っていList<String>ます。の重複を削除したいと思いArrayListます。これは、下流の処理を改善するためのものです。

私が考えることができる唯一のことは、処理された値のログを保持することです。繰り返し処理を繰り返し、HashMap以前ArrayListに値に遭遇したことがあるかどうかを確認します。このアプローチは、リストが大きくなるにつれてパフォーマンスが低下するようです。HashMap値から重複を削除するために前処理する方法はありArrayListますか?

説明すると... String1>List1 (a、b、c) String2>List2 (c、d、e) がある場合、「c」を削除して、HashMap 内のリスト全体で重複がないようにします。

4

6 に答える 6

1

値(アルファベット順、数値)で並べ替えることができる2番目のHashMapを作成し、並べ替えられたリストを1回スイープして、現在のノードが次のノードと同等かどうかを確認します。次のもの、そして増分を同じに保つので、それはそのソートされたリストの同じインデックスに残ります。

または、値を追加するときに、この値がすでに含まれているかどうかを確認できます。

于 2012-01-31T22:16:44.787 に答える
1

あなたの明確化を考えると、次のようなものが必要です:

class KeyValue {
    public String key;
    public Object value;

    KeyValue(String key, Object value) {
        this.key = key;
        this.value = value;
    }

    public boolean equals(Object o) {
        // boilerplate omitted, only use the value field for comparison
    }

    public int hashCode() {
        return value.hashCode();
    }
}

public void deduplicate() {
    Map<String, List<Object>> items = new HashMap<String, List<Object>>();
    Set<KeyValue> kvs = new HashSet<KeyValue>();

    for (Map.Entry<String, List<Object>> entry : items.entrySet()) {
        String key = entry.getKey();
        List<Object> values = entry.getValue();
        for (Object value : values) {
            kvs.add(new KeyValue(key, value));
        }
        values.clear();
    }

    for (KeyValue kv : kvs) {
        items.get(kv.key).add(kv.value);
    }
}

セットを使用すると、重複する値が削除KeyValueされ、その際に元のハッシュ キーを保持できます。必要に応じて、ゲッターとセッター、またはジェネリックを追加します。これにより、元のマップとその中のリストも変更されます。また、これに対するパフォーマンスは O(n) である必要があると思います。

于 2012-01-31T22:33:59.583 に答える
0

他の人が指摘したように、追加するときに値を確認できますが、事後にそれを行う必要がある場合:

static public void removeDups(Map<String, List<String>> in) {
        ArrayList<String> allValues = new ArrayList<String>();
        for (List<String> inValue : in.values())
           allValues.addAll(inValue);
        HashSet<String> uniqueSet = new HashSet<String>(allValues);

        for (String unique : uniqueSet)
            allValues.remove(unique);

        // anything left over was a duplicate
        HashSet<String> nonUniqueSet = new HashSet<String>(allValues);

        for (List<String> inValue : in.values())
           inValue.removeAll(nonUniqueSet);

     }


     public static void main(String[] args) {
        HashMap<String, List<String>> map = new HashMap<String, List<String>>();
        map.put("1", new ArrayList(Arrays.asList("a", "b", "c", "a")));
        map.put("2", new ArrayList(Arrays.asList("d", "e", "f")));
        map.put("3", new ArrayList(Arrays.asList("a", "e")));

        System.out.println("Before");
        System.out.println(map);

        removeDups(map);
        System.out.println("After");
        System.out.println(map);

     }

の出力を生成します

Before
{3=[a, e], 2=[d, e, f], 1=[a, b, c, a]}
After
{3=[], 2=[d, f], 1=[b, c]}
于 2012-01-31T22:57:55.277 に答える
0

グアバの使用:

Map<Value, Key> uniques = new LinkedHashMap<Value, Key>();
for (Map.Entry<Key, List<Value>> entry : mapWithDups.entrySet()) {
  for (Value v : entry.getValue()) {
    uniques.put(v, entry.getKey());
  }
}
ListMultimap<K, V> uniqueLists = Multimaps.invertFrom(Multimaps.forMap(uniques), 
  ArrayListMultimap.create());
Map<K, List<V>> uniqueListsMap = (Map) uniqueLists.asMap(); // only if necessary

値の順序を維持し、それらを一意に保つ必要があります。結果に aListMultimap<K, V>を使用できる場合 (おそらく使用できる場合)、それを使用します。それ以外の場合は、おそらくuniqueLists.asMap()aにキャストできますMap<K, List<V>>(ジェネリックの乱用がありますが、型の安全性が保証されています)。

于 2012-01-31T22:18:52.877 に答える
0

一意のリストではなく、一意の要素 (リストに含まれる) が必要であると想定しています。

マップのキーとそれに関連付けられたリスト内の要素との間の関連付けが必要ない場合は、すべての要素を個別にセットに追加するだけです。

すべてのリストをセットに追加すると、リストの一意の要素ではなく、一意のリスト オブジェクトが含まれるため、要素を個別に追加する必要があります。

(もちろん、addAllこれを簡単にするために を使用できます)

于 2012-01-31T22:17:32.567 に答える
0

だから、明確にするために...あなたは本質的にK、[V1 ... Vn]を持っていて、すべてのVに一意の値が必要ですか?

public void add( HashMap<String, List> map, HashMap<Objet, String> listObjects, String key, List values)
{
    List uniqueValues= new List();
    for( int i  = 0; i < values.size(); i++ ) 
    {
        if( !listObjects.containsKey( values.get(i) ) )
        {
            listObjects.put( values.get(i), key );
            uniqueValues.add( values.get(i) );
        }
    }
    map.put( key, uniqueValues);
} 

基本的に、リスト値を格納する別の HashMap があり、リストをマップに追加するときに一意でない値を削除します。これにより、値がどのリストに含まれているかを知ることができるという追加の利点も得られます。

于 2012-01-31T22:32:57.493 に答える