我正在尝试将对象添加到Treeset中,但不会添加所有对象。
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;
}
}
来自另一个类的public static void main。
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);
}
我得到的输出是:
--Fruits Example--
Apple-1-3
但是当我得到如下水果的时候,我得到了所有的物品 只保持一切,但第三个元素。 水果f1 =新水果(&#34; Apple&#34; 1,3); 水果f2 =新水果(&#34; Apple&#34; 1,1); 水果f3 =新水果(&#34; Apple&#34;,1,2);
输出get为
--Fruits Example--
Apple-1-1
Apple-1-2
Apple-1-3
因此,当我在重量和价格上保持不同的元素时,我的对象被视为相同。我无法弄清楚对象被视为同样的原因。请帮忙。
答案 0 :(得分:1)
树相关系列不使用equals()
或hashCode()
。这些对Map
发挥作用。
compare
中的条件会导致0
,因此未插入水果。
首先Apple进入,因为树是空的。第二&amp;在所有false
条件中,第3个Apple结果为if
,从而返回最终0
。在最终System.out.println()
之前加return
进行确认。
如果你想先按名称对水果进行分类,那么按重量计算&然后最终按价格,这是一个更紧凑的方式:
@Override
public int compare(Fruits f1, Fruits f2) {
if (f1.name.equals(f2.name)) {
if (f1.weight < f2.weight) {
return -1;
} else if (f1.weight > f2.weight) {
return 1;
} else {
if (f1.price < f2.price) {
return -1;
} else if (f1.price > f2.price) {
return 1;
} else {
return 0;
}
}
} else {
return f1.name.compareTo(f2.name);
}
}
答案 1 :(得分:1)
主要问题是,您始终检查两个字段是否相等,只有一个字段是不同的。 在最后的情况下,如果至少2个字段不同,则返回0,这意味着它们应该被视为相等,这就是你遇到这个问题的原因。
由于您要的订单首先按名称排序,然后按数量排序,然后按价格排序,从第4个条件开始删除&& f1.price == f2.price
,然后删除最后两个的&& f1.weight==f2.weight
。
如果使用Java 8样式,则可以完全避免此问题。
Set<Fruits> sf = new TreeSet<Fruits>(Comparator.comparing(Fruits::getName)
.thenComparing(Fruits::getWeight)
.thenComparing(Fruits::getPrice)
);
我在codiva - online java compiler ide添加了工作代码。我还在FruitsComparator.java文件中包含了一个稍微简洁的实现。
答案 2 :(得分:0)
您在课程equals
中的Fruits
方法出错:
if(this.name.equals(f.name) && this.price==f.price && this.weight == f.price)
应该是:
if(this.name.equals(f.name) && this.price==f.price && this.weight == f.weight)
(注意最后一部分)。
答案 3 :(得分:0)
TreeSet
,当与Comparator
一起使用时,元素的相等性由compare
的{{1}}方法决定,否则将使用Comparator
其元素的方法,因为它们需要实现compareTo
接口。 Comparable
和hashcode
方法仅由equals
接口本身使用(例如方法Set
使用contains
方法检查元素是否已呈现) 。在equals
使用hashcode
时,TreeSet
不是HashSet
使用的,这是实现Set
接口的另一种方式。因此,在您的代码中,由于您compare
覆盖的Comparator
方法将这些元素视为相等,因此无法多次插入它们。 Java Tutorial指出的一个指导原则是,compare
方法应符合equals
方法,即compare
方法中的元素应该被视为相等,当且仅当equals
方法。
在您的equals
方法中,您确实使用this.weight == f.price
来比较两个水果,我认为这不是您打算做的。这会使您的equals
方法与compare
方法不一致。
供您参考,请参阅Java Object Ordering教程,以及两天前我提出的a question。