I recently needed to determine the difference between an inbound set of data for an identifier (provided as a JSON object) and the same identifier stored in persistent storage.
Turns out that by converting the inbound data into a Map and the persisted record also into a Map, the com.google.collect.Maps class can be used to compare the two Maps. The following code shows how to return the difference as a JSON object containing the field name (key), the inbound value (left), the associated stored value (right) as well as any inbound data that was unmatched in the stored data.
Code
package org.pdd.util;
import java.util.ArrayList;
import java.util.Map;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.MapDifference;
import com.google.common.collect.MapDifference.ValueDifference;
public class Differences {
String key = "";
Object left = null;
Object right = null;
public Object getLeft() {
return left;
}
public void setLeft(Object left) {
this.left = left;
}
public Object getRight() {
return right;
}
public void setRight(Object right) {
this.right = right;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
/**
* Compare the left side map against the right side map and return a json
* object containing the differences in the values and the values that are
* provided on the left side but not provided on the right side.
*
* This is intended to be used in comparing an input set of values (the left
* side) against a stored set of values (the right side), with the intention
* of updating the stored values with the updated and/or new values from the
* input.
*
* @param left
* the input values
* @param right
* the stored values
* @return A JSON formatted string of the update values
*/
public static String arrayOfDifferences(Map left,
Map right) {
ArrayList differences = new ArrayList();
MapDifference valueDifferences = com.google.common.collect.Maps
.difference(left, right);
Map<String, ValueDifference> diff = valueDifferences
.entriesDiffering();
for (String key : diff.keySet()) {
ValueDifference values = diff.get(key);
Differences difference = new Differences();
difference.setKey(key);
difference.setLeft(values.leftValue());
difference.setRight(values.rightValue());
differences.add(difference);
}
Map onlyOnLeft = valueDifferences.entriesOnlyOnLeft();
for (String key : onlyOnLeft.keySet()) {
Differences difference = new Differences();
difference.setKey(key);
difference.setLeft(onlyOnLeft.get(key));
difference.setRight(null);
differences.add(difference);
}
ObjectMapper mapper = new ObjectMapper();
try {
return (String) mapper.writeValueAsString(differences);
} catch (JsonProcessingException e) {
e.printStackTrace();
return "[]";
}
}
}