Skip to content

Instantly share code, notes, and snippets.

@Groxx
Created June 10, 2015 21:29
Show Gist options
  • Save Groxx/2f1033947b3ba169729d to your computer and use it in GitHub Desktop.
Save Groxx/2f1033947b3ba169729d to your computer and use it in GitHub Desktop.
"find differences between data sets X and Y" helper
public class Diff<Type> {
public interface Finder<Type> {
/** Return true to denote a "represents the same thing" match (do not compare contents) */
boolean find(Type left, Type right);
}
public interface Equality<Type> {
boolean equals(Type left, Type right);
}
private final Finder<Type> finder;
private final Equality<Type> detector;
private final List<Type> added = new ArrayList<>();
private final List<Type> removed = new ArrayList<>();
private final List<Pair<Type, Type>> changed = new ArrayList<>();
public Diff(Finder<Type> finder, Equality<Type> detector) {
this.finder = finder;
this.detector = detector;
}
public void populate(List<Type> left, List<Type> right) {
// TODO: ok, so not strictly correct.
ASSERT(isEmpty(), "Must not have populated already");
List<Type> rightCopy = new ArrayList<>(right);
for (Type l : left) {
Type found = null;
for (Iterator<Type> i = rightCopy.iterator(); i.hasNext(); ) {
Type r = i.next();
if (finder.find(l, r)) {
found = r;
i.remove();
break;
}
}
if (found == null) {
removed.add(l);
} else if (!detector.equals(l, found)) {
changed.add(new Pair<>(l, found));
}
}
for (Type r : rightCopy) {
added.add(r);
}
}
public List<Type> getAdded() {
return added;
}
public List<Type> getRemoved() {
return removed;
}
public List<Pair<Type, Type>> getChanged() {
return changed;
}
public boolean isEmpty() {
return added.isEmpty() && removed.isEmpty() && changed.isEmpty();
}
}
// use:
Diff<Thing> diff =
new Diff<>(
// how to find equivalent things
(a,b) -> a.getId().equals(b.getId(),
// how to check for updates.
(a,b) -> a.latitude == b.latitude &&
a.longitude == b.longitude &&
a.speed = b.speed);
diff.populate(oldData, newData);
diff.getAdded() // returns all new ID things
diff.getRemoved() // returns all things that have disappeared
diff.getChanged() // returns Pair<old, new> so you can figure out how to handle each one
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment