How to compare two maps by their values

前端 未结 13 916
囚心锁ツ
囚心锁ツ 2020-12-08 12:09

How to compare two maps by their values? I have two maps containing equal values and want to compare them by their values. Here is an example:

    Map a = ne         


        
相关标签:
13条回答
  • 2020-12-08 12:20

    The result of equals in your example is obviously false because you are comparing the map a with some values in it with an empty map b (probably a copy and paste error). I recommend to use proper variable names (so you can avoid these kinds of errors) and make use of generics, too.

        Map<String, String> first = new HashMap<String, String>();
        first.put("f"+"oo", "bar"+"bar");
        first.put("fo"+"o", "bar"+"bar");
    
        Map second = new HashMap();
        second.put("f"+"oo", "bar"+"bar");
        second.put("fo"+"o", "bar"+"bar");
    
        System.out.println("equals: " + first.equals(second));
    

    The concatenation of your strings doesn't have any effect because it will be done at compile time.

    0 讨论(0)
  • 2020-12-08 12:22

    All of these are returning equals. They arent actually doing a comparison, which is useful for sort. This will behave more like a comparator:

    private static final Comparator stringFallbackComparator = new Comparator() {
        public int compare(Object o1, Object o2) {
            if (!(o1 instanceof Comparable))
                o1 = o1.toString();
            if (!(o2 instanceof Comparable))
                o2 = o2.toString();
            return ((Comparable)o1).compareTo(o2);
        }
    };
    
    public int compare(Map m1, Map m2) {
        TreeSet s1 = new TreeSet(stringFallbackComparator); s1.addAll(m1.keySet());
        TreeSet s2 = new TreeSet(stringFallbackComparator); s2.addAll(m2.keySet());
        Iterator i1 = s1.iterator();
        Iterator i2 = s2.iterator();
        int i;
        while (i1.hasNext() && i2.hasNext())
        {
            Object k1 = i1.next();
            Object k2 = i2.next();
            if (0!=(i=stringFallbackComparator.compare(k1, k2)))
                return i;
            if (0!=(i=stringFallbackComparator.compare(m1.get(k1), m2.get(k2))))
                return i;
        }
        if (i1.hasNext())
            return 1;
        if (i2.hasNext())
            return -1;
        return 0;
    }
    
    0 讨论(0)
  • 2020-12-08 12:23

    Since you asked about ready-made Api's ... well Apache's commons. collections library has a CollectionUtils class that provides easy-to-use methods for Collection manipulation/checking, such as intersection, difference, and union.

    0 讨论(0)
  • 2020-12-08 12:24

    @paweloque For Comparing two Map Objects in java, you can add the keys of a map to list and with those 2 lists you can use the methods retainAll() and removeAll() and add them to another common keys list and different keys list. Using the keys of the common list and different list you can iterate through map, using equals you can compare the maps.

    The below code will give output like this: Before {zoo=barbar, foo=barbar} After {zoo=barbar, foo=barbar} Equal: Before- barbar After- barbar Equal: Before- barbar After- barbar

    package com.demo.compareExample
    
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.List;
    import java.util.Map;
    
    import org.apache.commons.collections.CollectionUtils;
    
    public class Demo 
    {
        public static void main(String[] args) 
        {
            Map<String, String> beforeMap = new HashMap<String, String>();
            beforeMap.put("foo", "bar"+"bar");
            beforeMap.put("zoo", "bar"+"bar");
    
            Map<String, String> afterMap = new HashMap<String, String>();
            afterMap.put(new String("foo"), "bar"+"bar");
            afterMap.put(new String("zoo"), "bar"+"bar");
    
            System.out.println("Before "+beforeMap);
            System.out.println("After "+afterMap);
    
            List<String> beforeList = getAllKeys(beforeMap);
    
            List<String> afterList = getAllKeys(afterMap);
    
            List<String> commonList1 = beforeList;
            List<String> commonList2 = afterList;
            List<String> diffList1 = getAllKeys(beforeMap);
            List<String> diffList2 = getAllKeys(afterMap);
    
            commonList1.retainAll(afterList);
            commonList2.retainAll(beforeList);
    
            diffList1.removeAll(commonList1);
            diffList2.removeAll(commonList2);
    
            if(commonList1!=null & commonList2!=null) // athough both the size are same
            {
                for (int i = 0; i < commonList1.size(); i++) 
                {
                    if ((beforeMap.get(commonList1.get(i))).equals(afterMap.get(commonList1.get(i)))) 
                    {
                        System.out.println("Equal: Before- "+ beforeMap.get(commonList1.get(i))+" After- "+afterMap.get(commonList1.get(i)));
                    }
                    else
                    {
                        System.out.println("Unequal: Before- "+ beforeMap.get(commonList1.get(i))+" After- "+afterMap.get(commonList1.get(i)));
                    }
                }
            }
            if (CollectionUtils.isNotEmpty(diffList1)) 
            {
                for (int i = 0; i < diffList1.size(); i++) 
                {
                    System.out.println("Values present only in before map: "+beforeMap.get(diffList1.get(i)));
                }
            }
            if (CollectionUtils.isNotEmpty(diffList2)) 
            {
                for (int i = 0; i < diffList2.size(); i++) 
                {
                    System.out.println("Values present only in after map: "+afterMap.get(diffList2.get(i)));
                }
            }
        }
    
        /**getAllKeys API adds the keys of the map to a list */
        private static List<String> getAllKeys(Map<String, String> map1)
        {
            List<String> key = new ArrayList<String>();
            if (map1 != null) 
            {
                Iterator<String> mapIterator = map1.keySet().iterator();
                while (mapIterator.hasNext()) 
                {
                    key.add(mapIterator.next());
                }
            }
            return key;
        }
    }
    

    0 讨论(0)
  • 2020-12-08 12:25

    If anyone is looking to do it in Java 8 streams below is the example.

    import java.util.HashMap;
    import java.util.Map;
    
    public class CompareTwoMaps {
    
        public static void main(String[] args) {
    
            Map<String, String> a = new HashMap<>();
            a.put("foo", "bar" + "bar");
            a.put("zoo", "bar" + "bar");
    
            Map<String, String> b = new HashMap<>();
            b.put(new String("foo"), "bar" + "bar");
            b.put(new String("zoo"), "bar" + "bar");
    
            System.out.println("result = " + areEqual(a, b));
        }
    
        private static boolean areEqual(Map<String, String> first, Map<String, String> second) {
            return first.entrySet().stream()
                    .allMatch(e -> e.getValue().equals(second.get(e.getKey())));
        }
    }
    
    0 讨论(0)
  • 2020-12-08 12:27

    If you want to compare two Maps then, below code may help you

    (new TreeMap<String, Object>(map1).toString().hashCode()) == new TreeMap<String, Object>(map2).toString().hashCode()
    
    0 讨论(0)
提交回复
热议问题