从Java中删除HashMap中的重复值

时间:2013-07-23 14:02:14

标签: java hashmap duplicates

我有一个重复值的地图:

("A", "1");
("B", "2");
("C", "2");
("D", "3");
("E", "3");

我想要地图

("A", "1");
("B", "2");
("D", "3");

您知道如何摆脱重复的值吗?

目前,我收到'java.util.ConcurrentModificationException'错误。

谢谢。

public static void main(String[] args) {

    HashMap<String, String> map = new HashMap<String, String>();
    map.put("A", "1");
    map.put("B", "2");
    map.put("C", "2");
    map.put("D", "3");
    map.put("E", "3");

    Set<String> keys = map.keySet(); // The set of keys in the map.

    Iterator<String> keyIter = keys.iterator();

    while (keyIter.hasNext()) {
        String key = keyIter.next();
        String value = map.get(key);

        System.out.println(key + "\t" + value);

        String nextValue = map.get(key);

        if (value.equals(nextValue)) {
            map.remove(key);
        }
    }
    System.out.println(map);
}

10 个答案:

答案 0 :(得分:7)

制作反向HashMap!

HashMap<String, String> map = new HashMap<String, String>();
Set<String> keys = map.keySet(); // The set of keys in the map.

Iterator<String> keyIter = keys.iterator();

while (keyIter.hasNext()) {
    String key = keyIter.next();
    String value = map.get(key);
    map.put(value, key);
}

现在你有了hashMap,你需要反转它或打印它。

无论如何 在迭代hashMap时删除。将值保存在列表中并在外循环中删除它们

答案 1 :(得分:4)

    Map<String,Object> mapValues = new HashMap<String,Object>(5);
    mapValues.put("1", "TJ");
    mapValues.put("2", "Arun");
    mapValues.put("3", "TJ");
    mapValues.put("4", "Venkat");
    mapValues.put("5", "Arun");

    Collection<Object> list = mapValues.values();
    for(Iterator<Object> itr = list.iterator(); itr.hasNext();)
    {
        if(Collections.frequency(list, itr.next())>1)
        {
            itr.remove();
        }
    }

答案 2 :(得分:3)

假设您使用 Java 8 ,可以使用带有Set<String>的{​​{3}}来存储现有值:

Map<String, String> map = new HashMap<>();
map.put("A", "1");
...
System.out.printf("Before: %s%n", map);

// Set in which we keep the existing values
Set<String> existing = new HashSet<>();
map = map.entrySet()
    .stream()
    .filter(entry -> existing.add(entry.getValue()))
    .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
System.out.printf("After: %s%n", map);     

<强>输出:

Before: {A=1, B=2, C=2, D=3, E=3}
After: {A=1, B=2, D=3}

NB:严格来说,过滤器的谓词不应该是有状态,它应该是无状态,如{{ 3}}以确保结果保持确定性正确,即使我们使用并行流也是如此。但是在这里,我假设你不打算使用并行流,这样这种方法仍然有效。

答案 3 :(得分:2)

ConcurrentModificationException正在发生,因为您要从map

中删除
  if (value.equals(nextValue)) {
            map.remove(key);
        }

您必须从iterator

中删除
if (value.equals(nextValue)) {
            keyIter.remove(key);
        }

出现重复输入问题,非常简单:Find duplicate values in Java Map?

答案 4 :(得分:1)

如果这是您的常见要求,那么DualHashBidiMap类的apache commons.collections 将会帮助您更多而不是使用HashMap

答案 5 :(得分:0)

这可以通过将hashmap放入arraylist来轻松完成。 这个arraylist是hashmap类型。

ArrayList<HashMap<String, String>> mArrayList=new ArrayList<>();
HashMap<String, String> map=new HashMap<>();
map.put("1", "1");
        mArrayList.add(map);
        map=new HashMap<>();
        map.put("1", "1"); 
        mArrayList.add(map);
        map=new HashMap<>();
        map.put("1", "2");
        mArrayList.add(map);
        map=new HashMap<>();
        map.put("1", "3");
        mArrayList.add(map);
        map=new HashMap<>();
        map.put("1", "2");
        mArrayList.add(map);

for(int i=0;i<mArrayList.size();i++)
        {
            temp=mArrayList.get(i).get("1");
            for(int k=i+1;k<mArrayList.size();k++)
            {
                if(temp.equals(mArrayList.get(k).get("1")))
                {
                    mArrayList.remove(k); 
                } 
            }

        }

现在打印你的arraylist ...很容易删除hashmap中的所有重复值...这是删除重复的最简单方法

答案 6 :(得分:0)

这将有助于从地图中删除重复的值。

    Map<String, String> myMap = new TreeMap<String, String>();
    myMap.put("1", "One");
    myMap.put("2", "Two");
    myMap.put("3", "One");
    myMap.put("4", "Three");
    myMap.put("5", "Two");
    myMap.put("6", "Three");

    Set<String> mySet = new HashSet<String>();

    for (Iterator itr = myMap.entrySet().iterator(); itr.hasNext();)
    {
        Map.Entry<String, String> entrySet = (Map.Entry) itr.next();

        String value = entrySet.getValue();

        if (!mySet.add(value))
        {
            itr.remove();               
        }
    }

System.out.println(&#34; mymap:&#34; + mymap);

输出:

mymap:{1 =一,二=两,四=三}

答案 7 :(得分:0)

public static void main(String[] args) {
    Map<String, String> map = new HashMap<>();
    map.put("A", "1");
    map.put("B", "2");
    map.put("C", "2");
    map.put("D", "3");
    map.put("E", "3");
    System.out.println("Initial Map : " + map);
    for (String s : new ConcurrentHashMap<>(map).keySet()) {
        String value = map.get(s);
        for (Map.Entry<String, String> ss : new ConcurrentHashMap<>(map)
                .entrySet()) {
            if (s != ss.getKey() && value == ss.getValue()) {
                map.remove(ss.getKey());
            }
        }
    }
    System.out.println("Final Map : " + map);
}

答案 8 :(得分:0)

这可以使用Java 8完成。流的概念是必需的。伪代码, 是stream()。filter()。collect()。 如果初始地图:{A = 1,B = 2,C = 2,D = 3,E = 3}。然后删除重复项后所需的答案是{A = 1,B = 2,D = 3}。

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

public class RemoveDuplicates1 {
   public static void main(String[] args) {

        //Initial Map : {A=1, B=2, C=2, D=3, E=3}
        //After =>  {A=1, B=2, D=3} 

      Map<String , String > map = new HashMap<>();
        map.put("A", "1");
        map.put("B", "2");
        map.put("C", "2");
        map.put("D", "3");
        map.put("E", "3");

        System.out.printf("before :   " +map );
        System.out.println("\n");

        Set<String> set = new  HashSet<>();

        map = map.entrySet().stream()
                .filter(entry -> set.add(entry.getValue()))
                .collect(Collectors.toMap(Map.Entry :: getKey ,  Map.Entry :: getValue));
        System.out.printf("after => " + map);

   }
}

答案 9 :(得分:0)

如果您只是想删除并发修改异常,则只需用ConcurrentHashMap替换HashMap。

要了解有关ConcurrentHashMap的更多信息,请查看here