重写compareTo()方法,findBugs()提示错误,帮看看是什么原因?

weichenggao 2011-04-19 03:46:17
1
...全文
465 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
amos1989 2011-04-20
  • 打赏
  • 举报
回复
看来都已经解决掉了
lxbccsu 2011-04-19
  • 打赏
  • 举报
回复
6楼的方法个人是不推荐的:
首先是compareTo()不能依赖equals();
其次增加了实现compareTo()的复杂性;特别是多个字段时;
lxbccsu 2011-04-19
  • 打赏
  • 举报
回复

try {
Integer pre0 = Integer.parseInt(obj.getStrDiskID().replace("DISK",""));
Integer pre1 = Integer.parseInt(getStrDiskID().replace("DISK", ""));
if(pre0 < pre1){
return 1;
}
}catch(NumberFormatException e) {

}

这些代码是多余的,保留的原因是楼主这么写了。
这是最后的说明。
若鱼1919 2011-04-19
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 magong 的回复:]
大家都说了,不过应该怎么改没怎么说,
比较方便的改法是增加一个equals方法,覆盖父类equals方法,方法中这么写:

@Override
public boolean equals(Object obj) {
return (compareTo(obj)==0);
}
[/Quote]

妙!
lxbccsu 2011-04-19
  • 打赏
  • 举报
回复
还一个bug,修改:

public int compareTo(ServerDiskPhyInfo obj) {
if(this == obj) return 0;
if(obj == null) return 1;
if(this.equals(obj)) return 0;

if (null == obj.getStrDiskID())return 1;
if (null == this.strDiskID) return -1;

try {
Integer pre0 = Integer.parseInt(obj.getStrDiskID().replace("DISK",""));
Integer pre1 = Integer.parseInt(getStrDiskID().replace("DISK", ""));
if(pre0 < pre1){
return 1;
}
}catch(NumberFormatException e) {

}

return strDiskID.compareTo(obj.getStrDiskID());
}


测试:
public static void main(String[] args) {
ServerDiskPhyInfo obj1 = new ServerDiskPhyInfo();
obj1.setStrDiskID("DISK13");
System.out.println(obj1.equals(obj1)+ " " + obj1.compareTo(obj1));
System.out.println(obj1.equals(null)+ " " + obj1.compareTo(null));

System.out.println();
ServerDiskPhyInfo obj2 = new ServerDiskPhyInfo();
obj2.setStrDiskID("DISK13");
System.out.println(obj1.equals(obj2)+ " " + obj1.compareTo(obj2));
System.out.println(obj2.equals(obj1) + " " +obj2.compareTo(obj1));

System.out.println();
obj1.setStrDiskID(null);
System.out.println(obj2.equals(obj1)+ " " + obj2.compareTo(obj1));
System.out.println(obj1.equals(obj2)+ " " + obj1.compareTo(obj2));
obj2.setStrDiskID(null);
System.out.println(obj2.equals(obj1)+ " " + obj2.compareTo(obj1));

System.out.println();
obj1.setStrDiskID("DISK12");
obj2.setStrDiskID("DISK13");
System.out.println(obj1.equals(obj2)+ " " + obj1.compareTo(obj2));
System.out.println(obj2.equals(obj1) + " " +obj2.compareTo(obj1));

System.out.println();
obj1.setStrDiskID("AISK12");
obj2.setStrDiskID("DISK13");
System.out.println(obj1.equals(obj2)+ " " + obj1.compareTo(obj2));
System.out.println(obj2.equals(obj1) + " " +obj2.compareTo(obj1));
}

lxbccsu 2011-04-19
  • 打赏
  • 举报
回复
只能连续回答3次

再有,equals和hashCode方法表现行为要一致,
从你代码中看只要比较strDiskID,上面的方法得重写。
补上:
public int compareTo(ServerDiskPhyInfo obj) {
if(this == obj) return 0;
if(obj == null) return 1;

if (null == obj.getStrDiskID())return 1;
if (null == this.strDiskID) return -1;

try {
Integer pre0 = Integer.parseInt(obj.getStrDiskID().replace("DISK",""));
Integer pre1 = Integer.parseInt(getStrDiskID().replace("DISK", ""));
if(pre0 < pre1){
return 1;
}
}catch(NumberFormatException e) {

}

return strDiskID.compareTo(obj.getStrDiskID());
}

@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((strDiskID == null) ? 0 : strDiskID.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;
ServerDiskPhyInfo other = (ServerDiskPhyInfo) obj;
if (strDiskID == null) {
if (other.strDiskID != null)
return false;
} else if (!strDiskID.equals(other.strDiskID))
return false;
return true;
}
magong 2011-04-19
  • 打赏
  • 举报
回复
大家都说了,不过应该怎么改没怎么说,
比较方便的改法是增加一个equals方法,覆盖父类equals方法,方法中这么写:

@Override
public boolean equals(Object obj) {
return (compareTo(obj)==0);
}
lxbccsu 2011-04-19
  • 打赏
  • 举报
回复
Generally, the value of compareTo should return zero if and only if equals returns true. If this is violated, weird and unpredictable failures will occur in classes such as PriorityQueue. In Java 5 the PriorityQueue.remove method uses the compareTo method, while in Java 6 it uses the equals method.
这里更是说了compareTo return 0时,只有当equals方法return true;
如队列PriorityQueue, 使用PriorityQueue.remove 方法时,JDK5使用的是对象的compareTo方法,JDK1.6中使用了equals方法,所以为了保持一致,应该(x.compareTo(y)==0) == (x.equals(y)).
lxbccsu 2011-04-19
  • 打赏
  • 举报
回复
It is strongly recommended, but not strictly required that (x.compareTo(y)==0) == (x.equals(y)). 这里建议你当x.compareTo(y)==0)应满足(x.equals(y).
lxbccsu 2011-04-19
  • 打赏
  • 举报
回复
这里写的很清楚了:
Bug: com.ecm.hwm.server.entity.ServerDiskPhyInfo defines compareTo(ServerDiskPhyInfo) and uses Object.equals()
compareTo方法使用的是 Object.equals()
加上

public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + iDiskState;
result = prime * result
+ ((strDiskID == null) ? 0 : strDiskID.hashCode());
return result;
}

public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ServerDiskPhyInfo other = (ServerDiskPhyInfo) obj;
if (iDiskState != other.iDiskState)
return false;
if (strDiskID == null) {
if (other.strDiskID != null)
return false;
} else if (!strDiskID.equals(other.strDiskID))
return false;
return true;
}

把==改为
aotian16 2011-04-19
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 goldenfish1919 的回复:]

the value of compareTo should return zero if and only if equals returns true
(x.compareTo(y)==0) == (x.equals(y))
所以,需要你重写equals方法,而不是使用从Object继承而来的equals
[/Quote]

我觉得这句话的意思是这样吧
  @Override
public int compareTo(ServerDiskPhyInfo o)
{
if (this.equals(o))
{
return 0;
}

if (null == o.getStrDiskID())
{
return 1;
}
if (null == this.strDiskID)
{
return -1;
}

不知道理解对不对
若鱼1919 2011-04-19
  • 打赏
  • 举报
回复
the value of compareTo should return zero if and only if equals returns true
(x.compareTo(y)==0) == (x.equals(y))
所以,需要你重写equals方法,而不是使用从Object继承而来的equals

62,615

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧