I have an equals method to compare some attributes, this is how it looks:
public boolean Complementos(COSTOS obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
COSTOS other = (COSTOS) obj;
if (NumeroParte == null) {
if (other.NumeroParte != null)
return false;
} else if (!NumeroParte.equals(other.NumeroParte))
return false;
if (descripcion == null) {
if (other.descripcion != null)
return false;
} else if (!descripcion.equals(other.descripcion))
return false;
if (Double.doubleToLongBits(monto) != Double.doubleToLongBits(other.monto))
return false;
if (referencia != other.referencia)
return false;
return true;
}
But besides to see if the attributes are equals, i want to return a value from "compareToIgnoreCase" from the attributes "-1, 0, 1" and i'm not allow to do it because of the method that is boolean and i tried to make it "int" but that would just mark as error my "return false/true", so... could i use an exception? if i could... how could i implemented?
Thanks
You could use an exception to convey this, but you definitely shouldn't. Exceptions are for exceptional circumstances and shouldn't be used to control the flow of your application.
Generally speaking, if you have a method that needs to return more than one output then you should split it into multiple methods. This makes your code more reusable and your APIs less confusing.
In the rare case where you can't do this, you can return an object representing the result of the method. For example:
#Transactional
public LoginResponse login(String username, char[] password);
Related
I'm studying object oriented programming in Java at my school and I had to do an exercise to compare Circles.
I had the Circle Class with these
private int id;
private String bgColor;
private String fgColor;
And inside it I had to use the equals method to compare two circles (by using these three attributes): a circle is equal to other circle if its radius and the bg and fgColor are the same.
public boolean equals(Object obj) {
boolean found;
if (obj == null) {
found = false;
}
if (getClass() != obj.getClass()) {
found = false;
}
final Circle other = (Circle) obj;
if (Double.doubleToLongBits(this.radius) == Double.doubleToLongBits(other.radius)) {
//found = false;
if (Objects.equals(this.bgColor, other.bgColor)) {
//found = false;
if (Objects.equals(this.fgColor, other.fgColor)) {
return true;
}//end if fgColor
else{
found = false;
}
}//end if bgcolor
else{
found = false;
}
}//end if radius
else{
found = false;
}
return found;
}
But my teacher told me that the code above is "confusing", but I don't understand why.
Do you know a better solution?
My teacher wants that we folow this structure (this case is only comparing one property):
public boolean equals (Object obj)
{
boolean b;
if(obj == null)
{
b = false;
}
else
{
if(this == obj)//same object
{
b = true;
}
else
{
if(obj instanceof Book)
{
Book other = (Book) obj;
b = (this.id == other.id);
}
else
{
b = false;
}
}
}
return b;
}
This is about the most concise version (assuming that radius and colors can't be null). The null check for obj is taken care of by the instanceof test:
public boolean equals(Object obj) {
if( ! (obj instanceof Circle ) )
return false;
Circle rhs = (Circle)obj;
return Double.compare( radius, rhs.radius ) == 0 &&
bgColor.equals( rhs.bgColor ) &&
fgColor.equals( rhs.fgColor );
}
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
// its a Circle so its safe to case
Circle other = (Circle)obj;
// equals ONLY if 3 conditions are met
if (radius == other.getRadius() &&
bgColor.equals(other.getBgColor()) &&
fgColor.equals(other.getFgColor())){
return true;
}
return false;
}
If you are using a IDE (I hope you do) probably it has an option to generate code for equals method.
Eclipse generates something like:
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Circle other = (Circle) obj;
if (bgColor == null) {
if (other.bgColor != null)
return false;
} else if (!bgColor.equals(other.bgColor))
return false;
if (fgColor == null) {
if (other.fgColor != null)
return false;
} else if (!fgColor.equals(other.fgColor))
return false;
if (Double.doubleToLongBits(radius) != Double.doubleToLongBits(other.radius))
return false;
return true;
}
And don't forget implements hashcode method when you implements equals method and vicecersa.
Rather than having a single return statement consider using multiple return points to simplify the code. This way you do not need extra boolean variables to hold on to the results of prior conditions.
public class Circle {
public double radius;
public String bgColor;
public String fgColor;
public boolean equals(Object obj) {
if (obj == null) {
return false;
} else if (obj instanceof Circle) {
Circle other = (Circle) obj;
if (Double.compare(this.radius, other.redius) == 0
&& compareStrings(this.fgColor, other.fgColor)
&& compareStrings(this.bgColor, other.bgColor)) {
return true;
} else {
return false;
}
} else {
return false;
}
}
private boolean compareStrings(String a, String b) {
if (a == null && b == null) {
return true;
} else if (a != null) {
return a.equals(b);
} else if (b != null) {
return b.equals(a);
}
return false;
}
}
This solution allows for the possibility that either of the String fgColor or bgColor might be null without throwing a NPE. The String comparison has been extracted into its own function to aid readability and reduce confusion.
As a follow-up to my previous answer:
Writing an equals method that works correctly in the presence of subclassing is extremely non-trivial (see Joshua Bloch's comments in Item 8 of `Effective Java').
Indeed, until relatively recently the was no widely known single method for doing this.
In 2009, the article "How to Write an Equality Method in Java"
by Martin Odersky, Lex Spoon, and Bill Venners shows that this can be achieved in terms of a `canEqual' method.
I am writing an equals method in which two names are considered equal if they have the same first, middle, and last names. However, I keep getting the error
"This class defines a covariant version of the equals() method, but
inherits the normal equals(Object) method defined in the base
java.lang.Object class. The class should probably define a boolean
equals(Object) method."
and when I change it to Object other as the parameter, I get a "no such method" error.
public boolean equals(Name other) {
boolean sameFirstName = firstName.equals(other.firstName);
boolean sameMiddleName = middleName.equals(other.middleName);
boolean sameLastName = lastName.equals(other.lastName);
if (sameFirstName && sameMiddleName && sameLastName) {
return true;
}
return false;
}
You have to use Object type for parameter which called 'other'. Then do instance of checking and casting. Please refer to this answer
If you use Java 7 or higher, you can use this code:
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return Objects.equals(firstName, person.firstName) &&
Objects.equals(middleName, person.middleName) &&
Objects.equals(lastName, person.lastName);
}
And there is an automatically generated equals in IDE:
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return !(firstName != null ? !firstName.equals(person.firstName) : person.firstName != null)
&& !(middleName != null ? !middleName.equals(person.middleName) : person.middleName != null)
&& !(lastName != null ? !lastName.equals(person.lastName) : person.lastName != null);
}
Please notice that there should be NPE check as well.
You are overloading the method equals by having a different parameter to type Object. The following should work for you.
#Override
public boolean equals(Object object) {
if(this == object) return true;
if(!(object instanceof Name)) return false;
Name other = (Name) object;
boolean sameFirstName = firstName.equals(other.firstName);
boolean sameMiddleName = middleName.equals(other.middleName);
boolean sameLastName = lastName.equals(other.lastName);
if (sameFirstName && sameMiddleName && sameLastName) {
return true;
}
return false;
}
I have to override the equals() method and hascode() method for entity class.
But My question is why to use the HashcodeBuilder and EqualsBuilder to implement it.
Which one is better among this two and why ?
#Override
public int hashCode()
{
return HashCodeBuilder.reflectionHashCode(this, false);
}
#Override
public boolean equals(Object obj)
{
return EqualsBuilder.reflectionEquals(this, obj);
}
OR
#Override
public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result + ((userKey == null) ? 0 : userKey.hashCode());
result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result + ((userEntity == null) ? 0 : userEntity.hashCode());
return result;
}
#Override
public boolean equals(Object obj)
{
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
UserKeyEntity other = (UserKeyEntity) obj;
if (UserKey == null)
{
if (other.userKey != null)
return false;
}
else if (!userKey.equals(other.userKey))
return false;
if (id == null)
{
if (other.id != null)
return false;
}
else if (!id.equals(other.id))
return false;
if (userEntity == null)
{
if (other.userEntity != null)
return false;
}
else if (!userEntity.equals(other.userEntity))
return false;
return true;
}
and why?
the Second is by default created by the STS IDE.
Please tell me what exactly the 1st Option is about and why to prefer?
Personally, I wouldn't use reflection to compute equals and hashcode.
As the doc states (for EqualsBuilder.reflectionEquals):
It uses AccessibleObject.setAccessible to gain access to private
fields. This means that it will throw a security exception if run
under a security manager, if the permissions are not set up correctly.
It is also not as efficient as testing explicitly. Non-primitive
fields are compared using equals().
So
You are doing dangerous operations (and you are not even sure that you wouldn't get a SecurityException)
It's less effective because you use reflection to compute those values
As a personal point of view, I really feel like using reflection to compute equals and hashcode from your class is a non-sense. It's like using the wrong tool.
Since you are already using a third party library, I would use the HashCodeBuilder like this :
#Override
public int hashCode() {
return new HashCodeBuilder().append(userKey)
.append(id)
.append(userEntity)
.toHashCode();
}
and same with equals:
#Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
UserKeyEntity other = (UserKeyEntity) obj;
return new EqualsBuilder().append(userKey, other.userKey)
.append(id, other.id)
.append(userEntity, other.userEntity)
.isEquals();
}
which is a bit more readable than the ones generated by Eclipse, and don't use reflection.
HashcodeBuilder and EqualsBuilder will affect the performance because it uses reflection,it will be slower than than the second one.
You can use the one generated by IDE over HashcodeBuilder and EqualsBuilder.
HashcodeBuilder and EqualsBuilder will be easy to read, understand and its dynamic.
I am reading the Hashtable's code, and I learned that both Hashtable's key and value can not be null, but its equals method test the situation that value is null or not.
public synchronized boolean equals(Object o) {
if (o == this)
return true;
if (!(o instanceof Map))
return false;
Map<K,V> t = (Map<K,V>) o;
if (t.size() != size())
return false;
try {
Iterator<Map.Entry<K,V>> i = entrySet().iterator();
while (i.hasNext()) {
Map.Entry<K,V> e = i.next();
K key = e.getKey();
V value = e.getValue();
if (value == null) { // Can Hashtable's value be null?
if (!(t.get(key)==null && t.containsKey(key)))
return false;
} else {
if (!value.equals(t.get(key)))
return false;
}
}
} catch (ClassCastException unused) {
return false;
} catch (NullPointerException unused) {
return false;
}
return true;
}
It is kind of a pattern that is followed throughout to handle the NPE. Consider a simple class
public class HelloWorld {
String data;
}
If you generate hashCode() and equals() you will see this general pattern followed. As in this case
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
HelloWorld that = (HelloWorld) o;
if (data != null ? !data.equals(that.data) : that.data != null) return false;
return true;
}
#Override
public int hashCode() {
return data != null ? data.hashCode() : 0;
}
As you can see we always check for null. It is not mandatory but a good programming practice. I understand it makes no sense in the case of Hashtable's but as I mentioned earlier developers must have added this check to maintain a uniform pattern.
Update : As Tim has suggested Since Hashtable is subclassable, it is possible for a subclass to try to support null keys or values. So it is safe to do a null check.
How to Store unique objects to avoid the duplicates in java Set?
For example
Consider Employee object which (Employee Id, name, salary....)
list of employee of objects need to add in the Set.
We need to restrict the Set for the duplicate elements which need to identify by the "Employee Id.
What are the best way's to do?
If you are using an implementation of a java.util.Set, it should not allow duplicates as long as your equals and hashCode methods are implemented properly. Not sure why you have hashmap and hashtable as tags on your question though. Maybe you should rephrase your question and add the code that gives you issues?
Edit: considering your edit:
If you use a Set, your Employee should have the following methods:
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((id == null) ? 0 : id.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Employee other = (Employee) obj;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
return true;
}
Similarly to #Dirk, you can also use HashCodeBuilder and EqualsBuilder from org.apache.commons.
It would look like this:
#Override
public int hashCode() {
return new HashCodeBuilder()
.append(id)
.append(name)
.append(salary)
.toHashCode();
}
#Override
public boolean equals(Object obj) {
if (obj instanceof Employee) {
final Employee employee = (Employee) obj;
return new EqualsBuilder()
.append(id, employee.id)
.append(name, employee.name)
.append(salary, employee.salary)
.isEquals();
} else {
return false;
}
}
Set Stores unique object only
Eg:
Set set = new HashSet();
// Add elements to the set
set.add("a");//true
set.add("b");//true
set.add("c");//true
set.add("d");//true
set.add("a");//false
add will return false when you will try to store the object which is already in the Set