1

I want to compare 2 object as same class,i want to konw What's the difference between two filed of the object, for example,

public class Person{
  private String name;
  private int age;
  ......
}

Person person1 = new Person();
person1.setName("jim");
person2.setage(12);

Person person2 = new Person();
person2.setName("jason");
person2.setage(14);

public Map compare(person1,person2)?

tell me name is different and age is different?

5
  • Use reflection to check every field and compare it in both objects, then put the contents in a Map. Commented Dec 4, 2013 at 3:00
  • Is there any other way if i dont't use reflection Commented Dec 4, 2013 at 3:02
  • @JeroenVannevel Unless of course there is a getName() of getAge() method that we haven't seen yet :) Are you sure you cannot create these methods, @SummerZeng ? Commented Dec 4, 2013 at 3:03
  • You really wouldn't want to call every method manually.. Reflection is the way to go when it's about meta questions like this. I'll add a sample in some time when none have done so, I'm in the middle of something now. Commented Dec 4, 2013 at 3:04
  • I'm not sure why you can't do what you're saying, write the method and use it. Commented Dec 4, 2013 at 3:04

1 Answer 1

3

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.

Sign up to request clarification or add additional context in comments.

4 Comments

Should remove try/catch and check field null when do compare.
You cannot remove the try/catch. It's either that or throws. The fields can be null, a null value is caught by the instanceof requirement in every Equals() implementation. It will just return false as it should.
My mistake. I thought field. get doesn't throw checked exception. Do you think we should move try/catch to out side for statement?
@Loc: that's entirely up to you. The chances of these two exceptions appearing is very low, it doesn't really matter.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.