How to define multiple equals () for a class

I want to override the public boolean equals (Object obj) function for the name and age in my class named MyObject, the structure of which is shown below

public class MyObject{ private String name; private int age; } 

How can I?

@balusC:

How about this?

 vo = new MyObject() { public boolean equals(Object obj) { return ((MyObject)obj).name().equals(this.getName()); } vo = new MyObject() { public boolean equals(Object obj) { return ((MyObject)obj).age() == (this.getAge()); 
+4
source share
6 answers

Your question is a bit vague, but if the only goal is to have different sorting algorithms depending on which property you would like to use, rather use Comparator .

 public class Person { private String name; private int age; public static Comparator COMPARE_BY_NAME = new Comparator<Person>() { public int compare(Person one, Person other) { return one.name.compareTo(other.name); } } public static Comparator COMPARE_BY_AGE = new Comparator<Person>() { public int compare(Person one, Person other) { return one.age > other.age ? 1 : one.age < other.age ? -1 : 0; // Maybe compare by name here? Ie if same age, then order by name instead. } } // Add/generate getters/setters/equals()/hashCode()/toString() } 

which you can use as follows:

 List<Person> persons = createItSomehow(); Collections.sort(persons, Person.COMPARE_BY_NAME); System.out.println(persons); // Ordered by name. Collections.sort(persons, Person.COMPARE_BY_AGE); System.out.println(persons); // Ordered by age. 

Regarding the actual implementation of equals() , I would prefer it to return true when both Person objects are technically or naturally identical. For comparison with technical identity, you can use a PK created using DB:

 public class Person { private Long id; public boolean equals(Object object) { return (object instanceof Person) && (id != null) ? id.equals(((Person) object).id) : (object == this); } } 

or just compare each property for comparison on a natural identity:

 public class Person { private String name; private int age; public boolean equals(Object object) { // Basic checks. if (object == this) return true; if (object == null || getClass() != object.getClass()) return false; // Property checks. Person other = (Person) object; if (name == null ? other.name != null : !name.equals(other.name)) return false; if (age != other.age) return false; // All passed. return true; } } 

Remember to override hashCode() when you override equals() .

See also:

+6
source

I'm not quite sure what you were aiming for. The general expectation of equals () is that it returns false for null and objects of other classes and performs equality of values ​​in the corresponding fields of the class in question.

Although you can, of course, handle String and Integer as follows:

 public boolean equals(Object o) { if (o == null) return false; if (o instanceof String) return name.equals(o); if (o instanceof Integer) return ((Integer)o) == age; ... } 

this violates the contract for equals , so you cannot do this (except that everything happens not so strange).

equals is an equivalence relation , therefore it should be reflective, symmetrical and transitive. The symmetric part is key here, since if a.equals(b) then b.equals(a) . Both String and Integer will not do this for you.

If you only need helper functions that check if the name or age matches the given name / age, you can do this without using equals() :

 public boolean equalsName(String name) { return name.equals(this.name); } public boolean equalsAge(int age) { return age == this.age; } 
+3
source

Just keep it short and simple (aka KISS principle ): write setters and getters . Something like the following example:

 public class Person { private String name; private int age; public String getName() { return name; } public int getAge() { return age; } 

And then in the method you have to check, you can write:

 Person person = new Person(); if(person.getName().equals("Something")) doThis(); if(person.getAge() == 1337) doThat(); 
+2
source

if you want to redefine equals, it should look something like this:

 static private <T> boolean checkEquals(T t1, T t2) { return (t1 == null) ? (t2 == null) : t1.equals(t2); } @Override public boolean equals (Object o) { if (o instanceof MyObject) { MyObject obj = (MyObject)o; return checkEquals(this.name, obj.getName()) && this.age == o.getAge(); } else return false; } @Override public int hashCode() { // implement hashCode } 

You need to override both hashCode () and equals () or not. And you also need to make sure your class is final , otherwise there are potential traps with equals .

0
source

Not sure what you mean by "multiple equals ()". If you want to compare both fields, you just need to override the equals method as follows:

 public boolean equals( Object o ) { if ( o != null && o instanceof MyObject ) { MyObject m = (MyObject) o; if (this.name == null) return false; return this.name.eqauls(m.name) && this.age == m.age; } return false; } /// Compute a hash code for the pair. public int hashCode() { int code = name == null ? 0 : name.hashCode(); return code ^ age; } 

It is good practice to modify hashCode whenever you change equals, so the HashMap works efficiently with your object.

0
source
 public class MyObject { private String name; private int age; @Override public boolean equals(Object o){ if(o instanceof MyObject){ MyObject otherObject = (MyObject)o; if(name == null){ return otherObject.name == null && otherObject.age == age; } else { return name.equals(otherObject.name) && otherObject.age == age; } } else { return false; } } // When we overriding equals it is a good practice to override hashCode // for consistecy @Override public int hashCode(){ int nameCode = (name == null) ? 0 : name.hashCode(); // See Item 9 in book Effective Java 2nd Edition return 31 * nameCode + age; } } 
0
source

Source: https://habr.com/ru/post/1313955/


All Articles