Java сравнить две карты

В java, я хочу сравнить две карты, как показано ниже, есть ли у нас API для этого?

Спасибо

Map<String, String> beforeMap ;
beforeMap.put("a", "1");
beforeMap.put("b", "2");
beforeMap.put("c", "3");

Map<String, String> afterMap ;
afterMap.put("a", "1");
afterMap.put("c", "333");

//--- it should give me:
b is missing, c value changed from '3' to '333'

Ответ 1

Я бы использовал функцию removeAll() для Set to, чтобы выполнять установление различий в ключах, чтобы находить дополнения и удаления. Фактические изменения можно обнаружить, выполнив разницу между наборами, используя запись, установленную как HashMap.Entry реализует equals(), используя как ключ, так и значение.

Set<String> removedKeys = new HashSet<String>(beforeMap.keySet());
removedKeys.removeAll(afterMap.keySet());

Set<String> addedKeys = new HashSet<String>(afterMap.keySet());
addedKeys.removeAll(beforeMap.keySet());

Set<Entry<String, String>> changedEntries = new HashSet<Entry<String, String>>(
        afterMap.entrySet());
changedEntries.removeAll(beforeMap.entrySet());

System.out.println("added " + addedKeys);
System.out.println("removed " + removedKeys);
System.out.println("changed " + changedEntries);

Выход

added []
removed [b]
changed [c=333]

Ответ 2

В классе Guava Maps есть некоторые методы для расчета различий между парой карт. Однако эти методы дают вам структуру данных, представляющую различия, а не довольно печатную строку.

Ответ 3

Для этого не нужно использовать компонент "из коробки". Вероятно, вам придется его кодировать, к сожалению. Хорошей новостью является то, что логика довольно проста.

Ответ 4

В зависимости от ваших конкретных потребностей вы можете также рассмотреть возможность использования других приложений, предназначенных для выполнения этой работы, например diff. Вы можете записать две карты в два разных файла и разделить файлы.

Ответ 5

Вы можете использовать пользовательский объект, содержащий ключ и значение (на самом деле Map делает это внутренне, скрыто от пользователя, поэтому мы не можем его использовать)

Поместите эти кортежи в Set

Чтобы сравнить два набора, преобразуйте их как в массивы, отсортируйте массивы и проведите оба массива от начала до конца параллельно, отменив первый массив, если он меньше, чем ключ во втором массиве, и наоборот.

class Tuple implements Comparable<Tuple>
{
    public String   key;
    public String   value;

    public Tuple(String key, String value)
    {
        this.key = key;
        this.value = value;
    }

    @Override
    public int compareTo(Tuple o)
    {
        return key.compareTo(o.key);
    }
}

public static void main(String[] args)
{
    // TreeSet is already sorted. If you use HashSet, use Arrays.sort()
    Set<Tuple> beforeSet = new TreeSet<>();
    beforeSet.add(new Tuple("a", "1"));
    beforeSet.add(new Tuple("b", "2"));
    beforeSet.add(new Tuple("c", "4"));

    Set<Tuple> afterSet = new TreeSet<>();
    afterSet.add(new Tuple("a", "1"));
    afterSet.add(new Tuple("c", "333"));
    afterSet.add(new Tuple("aa", "4"));

    Tuple[] beforeArray = beforeSet.toArray(new Tuple[beforeSet.size()]);
    Tuple[] afterArray = afterSet.toArray(new Tuple[afterSet.size()]);

    int beforePtr = 0;
    int afterPtr = 0;
    while (beforePtr < beforeArray.length || afterPtr < afterArray.length)
    {
        int difference = afterPtr >= afterArray.length? -1 : beforePtr >= beforeArray.length? 1 : beforeArray[beforePtr].compareTo(afterArray[afterPtr]);
        if (difference == 0)
        {
            if (!beforeArray[beforePtr].value.equals(afterArray[afterPtr].value))
            {
                System.out.println(beforeArray[beforePtr].key + " value changed from '" + beforeArray[beforePtr].value + "' to '" + afterArray[afterPtr].value + "'");
            }
            beforePtr++;
            afterPtr++;
        }
        else if (difference < 0)
        {
            System.out.println(beforeArray[beforePtr].key + " is missing");
            beforePtr++;
        }
        else
        {
            System.out.println(afterArray[afterPtr].key + " is added");
            afterPtr++;
        }
    }
}

Ответ 6

String output = new String();
for (String key:beforeMap.getKeys()){
  String beforeValue = beforeMap.getValue(key);
  String afterValue = afterMap.getValue(key);
  //nullsafe
  if(beforeValue.equals(afterValue){}
  else if (afterValue == null){
      output = output + key + " is missing, ";
      continue;
  }else {
      output = output + key + " has changed from " + beforeValue + " to " + afterValue + " , ";
  }
  afterMap.remove(key);

}

for (String key:afterMap.getKeys()){
    output = output + key + " was added with value " + afterMap.getValue(key) + ", ";
}

if(output == null){
    output = "Same map";
}
output = output.substring(0,output.length-2);
System.out.println(output);

Ответ 7

@user595234 Чтобы сравнить два Карты, вы можете добавить ключи карты в список, и с этими двумя списками вы можете использовать методы keepAll() и removeAll() и добавить их в другой общий список ключей и список ключей. Используя ключи общего списка и другого списка, вы можете выполнять итерацию по карте, используя равные вы можете сравнить карты.

    public class Demo
    {
           public static void main(String[] args) 
            {
                Map<String, String> beforeMap = new HashMap<String, String>();
                beforeMap.put("a", "1");
                beforeMap.put("b", "2");
                beforeMap.put("c", "3");

                Map<String, String> afterMap = new HashMap<String, String>();
                afterMap.put("a", "1");
                afterMap.put("c", "333");

                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);

                System.out.println("Common List of before map "+commonList1);
                System.out.println("Common List of after map "+commonList2);
                System.out.println("Diff List of before map "+diffList1);
                System.out.println("Diff List of after map "+diffList2);

                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;
            }
    }

Ниже приведен код:

До: {b=2, c=3, a=1}
После: {c=333, a=1}
Неравномерно: до- 3 после- 333
Равный: до - 1 после - 1
Значения присутствуют только перед картой: 2