Java TreeSet 未添加对象
Java TreeSet not adding object
我正在尝试将对象添加到 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;
}
}
来自另一个 class 的 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
但是当我有下面的水果对象时,我得到了所有的对象
除了第三个元素之外,一切都保持不变。
Fruits f1= new Fruits("Apple",1,3);
Fruits f2= new Fruits("Apple",1,1);
水果 f3= 新水果 ("Apple",1,2);
得到的输出是
--Fruits Example--
Apple-1-1
Apple-1-2
Apple-1-3
因此,当我在重量和价格上保留不同的元素时,我的物品会以某种方式被视为相同。我无法弄清楚为什么对象被视为相同。请帮忙。
您在 class Fruits
中的 equals
方法有错误:
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)
(注意最后一部分)。
树相关的集合不使用 equals()
或 hashCode()
。 Map
.
您在 compare
中的条件导致 0
,因此未插入水果。
第一个苹果进去,因为树是空的。第 2 个和第 3 个苹果在所有 if
条件下的结果为 false
,从而返回最终的 0
。在最后的 return
前放一个 System.out.println()
来确认。
如果您想先按名称对水果进行排序,然后按重量排序,最后按价格排序,这里有一个更简洁的方法:
@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);
}
}
TreeSet
,与Comparator
一起使用时,元素是否相等由Comparator
的compare
方法决定,否则使用[=14] =] 方法,因为它们需要实现 Comparable
接口。 hashcode
和 equals
方法只会被 Set
接口本身使用(例如方法 contains
使用 equals
方法来检查元素是否被呈现) . hashcode
不是 TreeSet
使用的东西,而 HashSet
使用它,这完全是实现 Set
接口的另一种方式。因此,在您的代码中,由于您重写了 Comparator
的 compare
方法将这些元素平等对待,因此它们不能被多次插入。 Java 教程指出的一个准则是,compare
方法应符合 equals
方法,也就是说,元素在 compare
方法中应被平等对待,如果并且仅当 equals
方法执行时。
并且在您的 equals
方法中,您确实使用了 this.weight == f.price
来比较两个水果,我认为这不是您打算做的。这使得您的 equals
方法与 compare
方法不一致。
参考一下Java Object Ordering tutorial, and as well as 我前两天问过
主要问题是,您总是检查两个字段是否相等,只有一个字段不同。
在最后,如果至少有 2 个字段不同,就会发生这种情况,你 return 0 这意味着它们应该被视为相等,这就是你遇到这个问题的原因。
由于你要的顺序是先按名称排序,再按数量排序,再按价格排序,从第4个条件开始去掉&& f1.price == f2.price
,去掉后两个的&& f1.weight==f2.weight
。
如果使用 Java8 样式,则可以完全避免此问题。
Set<Fruits> sf = new TreeSet<Fruits>(Comparator.comparing(Fruits::getName)
.thenComparing(Fruits::getWeight)
.thenComparing(Fruits::getPrice)
);
我已经在 codiva - online java compiler ide 中添加了工作代码。我还在 FruitsComparator.java 文件中包含了一个稍微简洁的实现。
我正在尝试将对象添加到 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;
}
}
来自另一个 class 的 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
但是当我有下面的水果对象时,我得到了所有的对象 除了第三个元素之外,一切都保持不变。 Fruits f1= new Fruits("Apple",1,3); Fruits f2= new Fruits("Apple",1,1); 水果 f3= 新水果 ("Apple",1,2);
得到的输出是
--Fruits Example--
Apple-1-1
Apple-1-2
Apple-1-3
因此,当我在重量和价格上保留不同的元素时,我的物品会以某种方式被视为相同。我无法弄清楚为什么对象被视为相同。请帮忙。
您在 class Fruits
中的 equals
方法有错误:
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)
(注意最后一部分)。
树相关的集合不使用 equals()
或 hashCode()
。 Map
.
您在 compare
中的条件导致 0
,因此未插入水果。
第一个苹果进去,因为树是空的。第 2 个和第 3 个苹果在所有 if
条件下的结果为 false
,从而返回最终的 0
。在最后的 return
前放一个 System.out.println()
来确认。
如果您想先按名称对水果进行排序,然后按重量排序,最后按价格排序,这里有一个更简洁的方法:
@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);
}
}
TreeSet
,与Comparator
一起使用时,元素是否相等由Comparator
的compare
方法决定,否则使用[=14] =] 方法,因为它们需要实现 Comparable
接口。 hashcode
和 equals
方法只会被 Set
接口本身使用(例如方法 contains
使用 equals
方法来检查元素是否被呈现) . hashcode
不是 TreeSet
使用的东西,而 HashSet
使用它,这完全是实现 Set
接口的另一种方式。因此,在您的代码中,由于您重写了 Comparator
的 compare
方法将这些元素平等对待,因此它们不能被多次插入。 Java 教程指出的一个准则是,compare
方法应符合 equals
方法,也就是说,元素在 compare
方法中应被平等对待,如果并且仅当 equals
方法执行时。
并且在您的 equals
方法中,您确实使用了 this.weight == f.price
来比较两个水果,我认为这不是您打算做的。这使得您的 equals
方法与 compare
方法不一致。
参考一下Java Object Ordering tutorial, and as well as
主要问题是,您总是检查两个字段是否相等,只有一个字段不同。 在最后,如果至少有 2 个字段不同,就会发生这种情况,你 return 0 这意味着它们应该被视为相等,这就是你遇到这个问题的原因。
由于你要的顺序是先按名称排序,再按数量排序,再按价格排序,从第4个条件开始去掉&& f1.price == f2.price
,去掉后两个的&& f1.weight==f2.weight
。
如果使用 Java8 样式,则可以完全避免此问题。
Set<Fruits> sf = new TreeSet<Fruits>(Comparator.comparing(Fruits::getName)
.thenComparing(Fruits::getWeight)
.thenComparing(Fruits::getPrice)
);
我已经在 codiva - online java compiler ide 中添加了工作代码。我还在 FruitsComparator.java 文件中包含了一个稍微简洁的实现。