Is it a good practise to use String#intern() in equals method of the class. Suppose we have a class:
public class A {
private String field;
private int number;
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final A other = (A) obj;
if ((this.field == null) ? (other.field != null) : !this.field.equals(other.field)) {
return false;
}
if (this.number != other.number) {
return false;
}
return true;
}
}
Will it be faster to use field.intern() != other.field.intern() instead of !this.field.equals(other.field).
No! Using
String.intern()implicitly like this is not a good idea:It will not be faster. As a matter of fact it will be slower due to the use of a hash table in the background. A
get()operation in a hash table contains a final equality check, which is what you want to avoid in the first place. Used like this,intern()will be called each and every time you callequals()for your class.String.intern()has a lot of memory/GC implications that you should not implicitly force on users of this class.If you want to avoid full blown equality checks when possible, consider the following avenues:
If you know that the set of strings is limited and you have repeated equality checks, you can use
intern()for the field at object creation, so that any subsequent equality checks will come down to an identity comparison.Use an explicit
HashMaporWeakHashMapinstead ofintern()to avoid storing strings in the GC permanent generation – this was an issue in older JVMs, not sure if it is still a valid concern.Keep in mind that if the set of strings is unbounded, you will have memory issues.
That said, all this sounds like premature optimization to me.
String.equals()is pretty fast in the general case, since it compares the string lengths before comparing the strings themselves. Have you profiled your code?