我希望以下内容能够返回true。
public class HudsonJob {
private String name;
private String status;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public boolean equals(Object jobName) {
return name.toLowerCase().equals(((String)jobName).toLowerCase());
}
public int hashCode() {
return name.hashCode();
}
}
,
List<HudsonJob> existingJbsLst = hudsonUtil.getAllJobs(); // returns multiple HudsonJob objects in the list.
我期望返回的声明是:
boolean isExistingJob = existingJbsLst.contains("AnExistingJOB");
总是回归假。
OR
boolean isExistingJob = existingJbsLst.equals("AnExistingJOB");
也返回false。
我应该在代码中添加/更改什么才能获得预期的返回值。
答案 0 :(得分:4)
您为equals
方法强制the contract。例如:
它是对称的:对于任何非空引用值x和y,当且仅当y.equals(x)返回true时,x.equals(y)才应返回true。
在您的情况下,job.equals(string)
可能属实,但string.equals(job)
将始终为假。
你的清单中可能发生的事情是,元素的比较是另一种方式:
for (Object el : list) {
if (parameter.equals(el)) {
...
}
}
这就是为什么它不起作用的技术原因:"AnExistingJOB".equals(jobObject)
总是错误的。
修改强>
顺便说一句,您的hashCode
方法也是错误的。如果在equals
方法中进行比较而忽略大小写,请在hashCode
中忽略它。 Bozho 的建议可能很好:IDE会更好地生成这些方法。此外,您可以查看 Andreas_D 的答案,了解有效的实施方法。
答案 1 :(得分:2)
您应该将HudsonJob
对象(不是String
)传递给contains(..)
方法。例如(如果添加以名称作为参数的构造函数):
boolean exists = existingJbsLst.contains(new HudsonJob("AnExistingJOB"));
让您的IDE生成equals
和hashCode
方法 - 它会添加正确的null
检查,类型检查等。
equals
的合同。 See here string.equalsIgnoreCase(..)
答案 2 :(得分:2)
第二个表达式确实应该返回false,因为您将List与String进行比较。如果第一个表达式返回false,那么显然列表中没有这样的作业。 equals的实现是正确的(好的,你应该测试'null'和相同的类)
在写关于缺失的测试时 - equals没有正确实现,它不应该是一个作业名而是一个HudsonJob对象:
public boolean equals(Object obj) {
if (obj == null) return false;
if (!(obj instanceof HudsonJob)) return false;
HudsonJob that = (HudsonJob) obj;
return this.name.equals(that.name);
}
答案 3 :(得分:1)
“contains”运算符循环遍历集合中的所有memer,并将“want”值与“found”值进行比较。我非常仔细地说。如果你说“joblist.contains(wantjob)”,这给了 - 省略了一些复杂性,相关部分:
for (HudsonJob gotjob : joblist)
{
if (wantjob.equals(gotjob))
return true;
}
也就是说,比较是“objectIAmLookingFor.equals(objectInList)”,而不是“objectInList.equals(objectIAmLookingFor)”。
因此,当你在一个字符串中搜索HudsonJob的列表时,它使用的是String.equals函数,而不是你的HudsonJob.equals函数。而String.equals对HudsonJobs一无所知,所以它会立即返回false。
有两种方法可以做你想要的。
一种方法是将您的HudsonJob.equals函数更改为
public boolean equals(Object o)
{
if (o==null || !(o instanceof HudsonJob))
return false;
return this.name.toLowerCase().equals(((HudsonJob)o).name.toLowerCase());
}
然后写
HudsonJob wantjob=new HudsonJob();
wantjob.setName("AnExistingJob");
if (existingJobList.contains(wantjob))
... whatever ...
另一种方法是不使用“包含”,而是编写自己的搜索功能,如:
public boolean jobInList(List<HudsonJob> existingJobs, String wantJob)
{
for (HudsonJob gotjob : existingJobs)
{
if (gotjob.name.toLowerCase().equals(wantJob.toLowerCase())
return true;
}
return false;
}
(实际上如果你需要toLowerCase,最好在循环之前做wantJob.toLowerCase,但无论如何。)
然后你可以说
if (jobInList(existingJobs,"AnExistingJob"))
... do something ...