GAK GAK - 5 months ago 15
Java Question

Java TreeSet not adding object

I am trying to add objects into a Treeset but the objects not all are getting added.

class Fruits
{
String name ;
int weight;
int price;

Fruits(String n, int w, int p)
{
this.name=n;
this.weight=w;
this.price =p;
}

@Override
public int hashCode() {
System.out.println("hashcode called");
int prime =31;
int result =1;
result = prime*result +(this.name.hashCode()+this.price+this.weight);
return result;
}

@Override
public boolean equals(Object obj) {
System.out.println("Equals called");
if(null!=obj)
{
Fruits f= (Fruits) obj;
if(this.name.equals(f.name) && this.price==f.price && this.weight == f.price)
{
return true;
}
}
return false;
}
}

class FruitsComparator implements Comparator<Fruits>
{
//Order by Name, then quanity and then Price
@Override
public int compare(Fruits f1, Fruits f2)
{
if(f1.name.equals(f2.name) && f1.weight == f2.weight && f1.price == f2.price)
{
System.out.println(1);
return 0;
}
else if(f1.name.equals(f2.name) && f1.weight==f2.weight && f1.price < f2.price)
{
System.out.println(2);
return -1;
}
else if (f1.name.equals(f2.name) && f1.weight==f2.weight && f1.price > f2.price)
{
System.out.println(3);
return 1;
}
else if (f1.name.equals(f2.name) && f1.weight<f2.weight && f1.price == f2.price)
{
System.out.println(4);
return -1;
}
else if (f1.name.equals(f2.name) && f1.weight>f2.weight && f1.price == f2.price)
{
System.out.println(5);
return 1;
}
else if (f1.name.compareTo(f2.name) <1 && f1.weight==f2.weight && f1.price == f2.price)
{
System.out.println(6);
return -1;
}
else if (f1.name.compareTo(f2.name) >1 && f1.weight==f2.weight && f1.price == f2.price)
{
System.out.println(7);
return 1;
}
return 0;
}
}


From public static void main of another class.

Fruits f1= new Fruits("Apple",1,3);
Fruits f2= new Fruits("Apple",10,1);
Fruits f3= new Fruits("Apple",15,2);
Set<Fruits> sf = new TreeSet<Fruits>(new FruitsComparator());
sf.add(f1);
sf.add(f2);
sf.add(f3);
System.out.println("--Fruits Example--");
for( Fruits f: sf)
{
System.out.println(f.name+"-"+f.weight+"-"+f.price);
}


The output I get is :

--Fruits Example--
Apple-1-3


But when I have fruits objs as below i get the all the objects
just keeping everything same but the third element.
Fruits f1= new Fruits("Apple",1,3);
Fruits f2= new Fruits("Apple",1,1);
Fruits f3= new Fruits("Apple",1,2);

The output get for this is

--Fruits Example--
Apple-1-1
Apple-1-2
Apple-1-3


So somehow my objects are treated as same when I keep different elements on weight and price. I couldn't figure out as why the objects are treated as same. Please help.

Answer

The primary issue is, you are always checking two fields to be equal and only one to be different. At the final else, that happens if at least 2 fields are different, you return 0 which means they should be treated as equal, and that is the reason you have this issue.

Since the order you want is to first sort by name, then by quantity and then by price, remove the && f1.price == f2.price from the 4th condition onwards, and remove && f1.weight==f2.weight on the last two.


I have added the working code in codiva - online java compiler ide. I have also included a slightly cleaner implementation in FruitsComparator.java file.