I have two java user defined java objects, how can i make these two objects to return same references with case ignore
Sample code:
public class compare{
private String name;
private Integer number;
}
java.lang.String has a method for this:
myString.equalsIgnoreCase("MyStRiNg");
If this is not what you are looking for please be more specific.
You must override hashcode and equals to properly compare two objects. The following is an IDE generated hashCode and equals method.
class A
{
#Override
public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((number == null) ? 0 : number.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;
A other = (A) obj;
if (name == null)
{
if (other.name != null)
return false;
}
else if (!name.equalsIgnoreCase(other.name))
return false;
if (number == null)
{
if (other.number != null)
return false;
}
else if (!number.equals(other.number))
return false;
return true;
}
String name;
Integer number;
}
Related
Award Entity
#JsonIgnore
#ManyToMany(mappedBy="awards", fetch=FetchType.LAZY)
private Set<Winner> winners = new HashSet<>();
Winner Entity
#ManyToMany(fetch=FetchType.LAZY)
#JoinTable(name="AWARD_ASSIGNMENT",
joinColumns={#JoinColumn(name="WINNER_ID", referencedColumnName="ID")},
inverseJoinColumns={#JoinColumn(name="AWARD_ID", referencedColumnName="ID")})
private Set<Award> awards = new HashSet<>();
I am calling this hibernate fetch method
return getSession().createQuery("from Winner").list();
Hashcode equals method overriding in Awards entity
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (int) (id ^ (id >>> 32));
result = prime * result + ((winners == null) ? 0 : winners.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;
Award other = (Award) obj;
if (id != other.id)
return false;
if (winners == null) {
if (other.winners != null)
return false;
} else if (!winners.equals(other.winners))
return false;
return true;
}
Winner entity
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((awards == null) ? 0 : awards.hashCode());
result = prime * result + (int) (id ^ (id >>> 32));
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Winner other = (Winner) obj;
if (awards == null) {
if (other.awards != null)
return false;
} else if (!awards.equals(other.awards))
return false;
if (id != other.id)
return false;
return true;
}
Overriding equals and hashcode methods as Many to Many relation is using SET.
Points to remember :
1) Make sure there are not Associations(One to many/ Many to many ..etc) in your hashcode or equal methods. while overriding hashcode / equals method use fields which make that object unique (ex.. FirstName + LastName + Phone number) try to avoid using PK Id generated by JPA .
2) Restrict Jackson/Json serialisation to avoid deep traversal .
#JsonManagedReference
private Set<Award> awards = new HashSet<>();
#JsonBackReference
private Set<Winner> winners = new HashSet<>();
I need to add an object to a list only when the given list does not already contain a object with similar properties
List<Identifier> listObject; //list
Identifier i = new Identifier(); //New object to be added
i.type = "TypeA";
i.id = "A";
if(!listObject.contains(i)) { // check
listObject.add(i);
}
I tried contains() to have a check on the existing list. If the list already has an object say j with j.type = "TypeA" and j.id = "A", I don't want to add that to list.
Can you please help me achieve this by overriding equals or any solution that can do?
Implement equals() and hashCode() in your Identifier class.
If you don't want to perform a check before adding the element, you can change your listObject from List to Set. A Set is a collection that contains no duplicate elements.
Follows an example of implementation automatically created by Eclipse IDE:
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result + ((type == null) ? 0 : type.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;
Identifier other = (Identifier) obj;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
if (type == null) {
if (other.type != null)
return false;
} else if (!type.equals(other.type))
return false;
return true;
}
I need help on to override the equals method. I have everything working except for the equals method. The equals method that I currently have is not giving me the correct answer. I can not seem to figure out what could be the problem.
My Class:
package myclasses;
public class Currency
{
private int dollars, cents;
public Currency()
{
dollars = 0;
cents = 0;
}
public Currency(int d, int c)
{
this.dollars = d;
this.cents = c;
setCents(cents);
}
public int getDollars()
{
return dollars;
}
public int getCents()
{
return cents;
}
private void setDollars(int dollars)
{
this.dollars = dollars;
}
private void setCents(int cents)
{
while(cents > 99)
{
cents = (cents - 100);
dollars++;
}
this.cents = cents;
}
public void setAmount(int newDollars, int newCents)
{
setDollars(dollars);
setCents(cents);
}
public void add(int dollars, int cents)
{
this.dollars = dollars + getDollars();
cents = cents + getCents();
setCents(cents);
}
public boolean equals(Object dollars, Object cents)
{
if(this == dollars && this == cents)
return true;
if(!(dollars instanceof Currency) || !(cents instanceof Currency))
return false;
Currency money = (Currency) dollars;
Currency penny = (Currency) cents;
return (this.dollars == money.dollars) && (this.cents == penny.cents);
//return Currency.dollars.equals(Currency.cents);
//return this.equals(dollars) && this.equals(cents);
}
public boolean isZero()
{
if(getDollars() == 0 && getCents() == 0)
{
return true;
}
return false;
}
public String toString()
{
return "$" + getDollars() + "." +
(getCents() < 10 ? ("0" + getCents()) : getCents());
}
}
Your equals() method has some errors like:
if(this == dollars && this == cents)
This will never be true... this must be:
if(this.dollars == dollars && this.cents == cents)
But I won't put any effort in coding the equals, is recommended to autogenerate equals. Something like this:
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Currency other = (Currency) obj;
if (cents != other.cents)
return false;
if (dollars != other.dollars)
return false;
return true;
}
Also is highly recommended, (nearly unavoidable as #AdriaanKoster commented) when you override equals() method, also override hashCode()
In equals() definition:
Note that it is generally necessary to override the hashCode method whenever this method is overridden, so as to maintain the general contract for the hashCode method, which states that equal objects must have equal hash codes.
Hash code:
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + cents;
result = prime * result + dollars;
return result;
}
I'm not quite sure why you are going the first check in your equals method. But I'll tell you how I am usually doing my equals method
public boolean equals(Object obj) {
if (this == obj) {
return true;
} else if (obj == null) {
return false;
} else if (getClass() != obj.getClass()) {
return false;
}
//a cast of object to the class you are using should be here
if (this.someField.equals(castObject.someField)
&& this.otherField.equals(castObject.otherField)) {
return true;
}
return false;
}
So here's what's happening. The first part of the method does basic checks - whether the object that you are testing is the same as the parameter, whether the object is null, and whether they are from the same class. Note that they are else if's because there are more than just those 3 cases.
If you've not entered any of the 3 initial conditional statements, you will need to make a cast of the obj parameter to the class that you are in. You are safe to do so because of the last if -
else if (getClass() != obj.getClass()) {
return false;
}
After that simply define the rule by which you determine whether two objects are the same. In the example that I'm using, I'm checking the contents of two fields of the class. If they are the same, then the objects are equal.
If you are overriding equals method, then your above code is not correctly overriding equals method.
use below code instead for overriding equals--
public boolean equals(Object currency) {
Currency newref = null;
if (currency instanceof Currency) {
newref = (Currency)currency;
}
return (this.dollars == newref.dollars) && (this.cents == newref.cents);
}
We all know that if equals method returns true, then two objects are equal.
Can anybody give an example where 2 objects have the same hash value but they are actually different?
I'm assuming you're familiar with the contract(s) associated with overriding equals() and hashCode(), and the implications of a collision-prone hashCode implementation. Given that, the following trivial example uses an object that holds two Integers and implements a very simple hashCode, and demonstrates how easy it is to have two objects that aren't equal but have the same hashCode. Providing a more sophisticated hashCode algorithm can alleviate this.
The output of running main is:
hashCodes: ih1: 6, ih2: 6
equals: false
Example code:
package example.stackoverflow;
public class IntHolder
{
private Integer primaryData;
private Integer secondaryData;
public IntHolder(Integer primaryData, Integer secondaryData)
{
this.primaryData = primaryData;
this.secondaryData = secondaryData;
}
#Override
public int hashCode()
{
return ((primaryData == null) ? 0 : primaryData.hashCode()) +
((secondaryData == null) ? 0 : secondaryData.hashCode());
}
#Override
public boolean equals(Object obj)
{
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
IntHolder other = (IntHolder) obj;
if (primaryData == null)
{
if (other.primaryData != null)
return false;
}
else if (!primaryData.equals(other.primaryData))
return false;
if (secondaryData == null)
{
if (other.secondaryData != null)
return false;
}
else if (!secondaryData.equals(other.secondaryData))
return false;
return true;
}
public static void main(String[] args)
{
IntHolder ih1 = new IntHolder(1, 5);
IntHolder ih2 = new IntHolder(3, 3);
System.out.println("hashCodes: ih1: " + ih1.hashCode() + ", ih2: " + ih2.hashCode());
System.out.println("equals: " + ih1.equals(ih2));
}
}
For reference, Eclipse's auto-generated hashCode() for the IntHolder class is:
#Override
public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result
+ ((primaryData == null) ? 0 : primaryData.hashCode());
result = prime * result
+ ((secondaryData == null) ? 0 : secondaryData.hashCode());
return result;
}
String str1="abcdef";
String str2="abcdfG";
They both have the same hashcode and equals method returns false.
public class Employee {
protected long employeeId;
public boolean equals(Object o){
if(o == null) return false;
if(!(o instanceof) Employee) return false;
Employee other = (Employee) o;
return this.employeeId == other.employeeId;
}
public int hashCode(){
return (int) this.employeeId;
}
}
In this example, we have overridden the equals method - two employees are equal when they will have same employee id.
If two Employee objects are equal, they will also have the same hash code.
Your Ans -
In this example, we also implemented the hash code - hashcode is the employeeId that is rounded down to an int. That means that many employee id's could result in the same hash code, but these Employee objects would still not be equal, since they don't have the same employee id.
How will I filter unique object from an arraylist.
List<LabelValue> uniqueCityListBasedState = new ArrayList<LabelValue>();
for (LabelValue city : cityListBasedState) {
if (!uniqueCityListBasedState.contains(city)) {
uniqueCityListBasedState.add(city);
}
}
This is my code. But the problem is that I need to filter not on the object but on the value of a property inside that object. In this case, I need to exclude the objects that has the name.
That is city.getName()
List<LabelValue> uniqueCityListBasedState = new ArrayList<LabelValue>();
uniqueCityListBasedState.add(cityListBasedState.get(0));
for (LabelValue city : cityListBasedState) {
boolean flag = false;
for (LabelValue cityUnique : uniqueCityListBasedState) {
if (cityUnique.getName().equals(city.getName())) {
flag = true;
}
}
if(!flag)
uniqueCityListBasedState.add(city);
}
Assuming you can change the list to set.
Use the Set Collection instead.
A Set is a Collection that cannot contain duplicate elements.
Overwrite the equals() and hashCode() methods of LabelValue (hashCode is not a must in this case):
String name;
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.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;
LabelValueother = (LabelValue) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
Here is one way to solve it.
You should override the equals() method and hashCode() of LabelValue.
And the equals() method should use the name property and so should the hashCode() method.
Then your code will work.
PS. Im assuming that your LabelValue objects can be distinguished with just the name property, which is what you seem to need anyway based on your question.