我有一个Treeset,其中人们用他们的钱分拣,但名字上是平等的。
我有杰克和杰基同名“杰基”,他们被认为是平等的。 {Tree> jack
已添加到树集中,jackie
不是。
contains()
上的javadoc说:
如果此set包含指定的元素,则返回true。更多 形式上,当且仅当此集合包含元素e时才返回true 这样(o == null?e == null:o.equals(e))。
不幸的是行
System.out.println(peoples.contains(jackie));
当jackie.equals(jack)
返回true时,返回false。为什么?
这是完整的代码。
public class UsingSet {
public static void main(String[] args) {
People jo = new People("Jo");
People jack = new People("Jackie");
jack.setMoney(12);
People jim = new People("Jimmy");
jim.setMoney(150);
People john = new People("John");
TreeSet<People> peoples = new TreeSet<People>();
peoples.add(jo);
peoples.add(jack);
peoples.add(jim);
peoples.add(john);
People jackie = new People("Jackie");
System.out.println("equality ? "+(jackie.equals(jack)));
System.out.println(peoples.contains(jackie));
}
}
class People extends Object implements Comparable<People> {
public static long maxCount() {
return 25000000000L;
}
String name;
Float money = 1000f;
public People(String name) {
super();
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.length());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
People other = (People) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
@Override
public String toString() {
return name;
}
@Override
public int compareTo(People other) {
int result = this.money.compareTo(other.getMoney());
if (result == 0){
//finding a second criteria
return this.name.compareTo(other.getName());
}else{
return result;
}
}
public float getMoney() {
return money;
}
public void setMoney(float money) {
this.money = money;
}
}
编辑:
javadoc表示基于自然顺序的Treeset必须与equals()
保持一致compareTo()
。带有Comparator
的Treeset不得。
所以我稍微修改了代码:
Comparator<People> compareByMoney = new Comparator<People>() {
@Override
public int compare(People p1, People p2) {
int result = p1.money.compareTo(p2.getMoney());
if (result == 0){
//finding a second criteria
return p1.name.compareTo(p2.getName());
}else{
return result;
}
}
};
TreeSet<People> peoples = new TreeSet<People>(compareByMoney);
...
System.out.println(peoples.contains(jackie)); //--> true
答案 0 :(得分:1)
jackie没有正式equals
来杰克,因为他们没有相同数额的钱(注意你的等号方法只检查名称,而不是钱)。
您正在使用money属性在树形图中比较它们。因为jackie有1000个钱,而jack有12个,所以它们对于树集并不相同,因此包含返回假..
如果你这样做
People jackie = new People("Jackie");
jackie.setMoney(12);
你输出两者都是真的,或者如果你的compareTo
方法只是:
@Override
public int compareTo(People other) {
return this.name.compareTo(other.getName());
}
它还会输出true
。
因此,您需要更改equals
方法以比较money
的数量,或者只使用compareTo
方法中的名称。
如果您阅读了文档:
注意由一组维护的排序(无论是否显式 比较器提供)必须与等于一致,如果是的话 正确实现Set接口。 (参见可比较者或比较者 用于与equals一致的精确定义。) 这是因为Set接口是根据equals定义的 操作,但TreeSet实例执行所有元素比较 使用compareTo(或compare)方法,因此有两个元素 从集合的角度来看,通过这种方法认为是相等的
一致:
C类的自然排序据说是一致的 等于当且仅当e1.compareTo(e2)== 0具有相同的布尔值时 作为C类的每个e1和e2的e1.equals(e2)
使用您的代码:
System.out.println("equality ? "+(jackie.equals(jack))); //equality ? true
System.out.println(jackie.compareTo(jack)); //1
你班级的自然顺序与平等不一致。所以不要指望你的treeSet具有正常的行为。
答案 1 :(得分:0)
我只是运行你的代码,然后打印出“真实”
答案 2 :(得分:0)
请理解二叉树拳以了解原因
compareTo()方法用于在树中插入任何元素(而不是equals()方法)。 杰克和杰克有不同的金额。因此,根据compartTo()方法,两者都不是同一个对象。并且因为compareTo()方法返回false。这就是为什么contains()方法也返回false
People jackie = new People("Jackie");
System.out.println("equality ? "+(jackie.equals(jack)));
System.out.println("compareTo ? "+(jackie.compareTo(jack)));
System.out.println(peoples.contains(jackie));
如果你的equals()方法返回true,那么你的compareTo()方法也应该显示相同的行为。
答案 3 :(得分:0)
我认为您没有注意到您的算法不符合您的目的。
好的,您将jack
和jackie
添加到TreeSet。
杰克得到name ="jackie"
和money="12"
杰基得到了name="jackie"
和money= <defaultValue> ="1000"
当你覆盖People类中的方法equals
时(主要是检查2对象的名称),你通过这种方式检查了"equality ? "+(jackie.equals(jack))
,这显然是真的
但是,当您在People类中覆盖方法compareTo
时,首先检查两个对象之间的资金,因此您之前声明jack
和jackie
没有相同的money属性值。实际上,它们是不同的,因为你的钱检查!= 0并且忽略了对名称的第二次检查。
好吧,如果你改变:
People jackie = new People("Jackie");
在
People jackie = new People("Jackie");
jackie.setMoney(12);
你启动它,魔术!
控制台输出:
equality ? true
true
问题解决了老兄