Here is a method to do it with Reflection:
public class Test {
public static void main(String[] args) {
Person person1 = new Person();
person1.name = "Jack";
person1.age = 18;
person1.favoriteSuperhero = "Superman";
Person person2 = new Person();
person2.name = "Jack";
person2.age = 20;
person2.favoriteSuperhero = "Superman";
Map<String, List<Object>> uncommonTraits = getUncommonTraits(person1, person2);
for(Entry<String, List<Object>> entry : uncommonTraits.entrySet()){
System.out.println(entry.getKey() + ":\t" + entry.getValue());
}
}
private static Map<String, List<Object>> getUncommonTraits(Person p1, Person p2) {
Map<String, List<Object>> result = new HashMap<>();
for(Field field : Person.class.getDeclaredFields()){
try {
if(!(field.get(p1).equals(field.get(p2)))){
result.put(field.getName(), new ArrayList<Object>(Arrays.asList(field.get(p1), field.get(p2))));
}
} catch (IllegalArgumentException | IllegalAccessException e) {
e.printStackTrace();
}
}
return result;
}
}
class Person {
public String name;
public int age;
public String favoriteSuperhero;
}
Output:
age: [18, 20]
This is very resistant to changes: if you add a field to your Person class, you won't have to change anything. It is also a bazillion times less redundant than manually checking each field.
I have used public fields for ease of use.
Map.getName()ofgetAge()method that we haven't seen yet :) Are you sure you cannot create these methods, @SummerZeng ?