2010-10-05 2 views
0

Я ожидаю, что следующее вернет 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

Вы должны либо добавить пустые чеки, или по умолчанию Инициализаторы .. так что ваш код не врезаться на нуль – Nix

+0

Это просто пример код, а не полный код, пожалуйста, возьмите цель – srinannapa

+0

Ваш пример путает людей. Пожалуйста, прямо покажите, как вы выполняете сравнения, и какие типы вы сравниваете. – Nix

ответ

1

Оператор «содержит» пропускает все элементы памяти набора и сравнивает значение «хотеть» с «найденным» значением. Я говорю это очень осторожно. Если вы говорите, "joblist.contains (wantjob)", это дает - оставить некоторую сложность, соответствующая часть:

for (HudsonJob gotjob : joblist) 
{ 
    if (wantjob.equals(gotjob)) 
    return true; 
} 

То есть, сравнение "objectIAmLookingFor.equals (objectInList)", а не " objectInList.equals (objectIAmLookingFor)».

Так что, когда вы просматриваете список HudsonJob для String, он использует функцию 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.toLow erCase перед циклом, но безотносительно.)

Тогда вы можете сказать

if (jobInList(existingJobs,"AnExistingJob")) 
... do something ... 
+0

Как насчет добавления toString() в класс HudsonJob, который возвращает 'this.name'. Таким образом, содержащий метод list ищет «AnExistingJOB» .equals (hudsonjob) -> строка hudsonjob для строки возвращает то же, что и я, проверяя выше, и возвращает true. - – srinannapa

+0

К сожалению, это не сработает. String.equals не сравнивает String с другим объектом .toString. Он проверяет, является ли другой объект строкой, а если нет, он возвращает false. Итак, String.equals (x), где x не является строкой, всегда возвращает false, period, end of story. – Jay

2
  • Вы должны пройти HudsonJob объект (а не String) к методу contains(..). Например (если добавить конструктор, принимающий имя в качестве параметра):

    boolean exists = existingJbsLst.contains(new HudsonJob("AnExistingJOB")); 
    
  • Пусть ваш IDE генерировать equals и hashCode методы - это добавит соответствующие null проверки, проверки типов и т.д.

  • You нарушают договор equals. See here
  • использование string.equalsIgnoreCase(..)
+0

Да «AnExistingJOB» - это работа hudson в моем контексте, скажем, – srinannapa

+0

это не так. Это «String». – Bozho

2

Второе выражение действительно должен возвращать ложь, потому что вы сравните список в строку. Если первое выражение возвращает false, то, очевидно, в списке нет такого задания. Реализация из равных верна (ОК, вы должны проверить «нуль» и для тех же классов)

При написании пропущенного теста - равнозначно, оно не должно выполняться правильно, оно не должно занимать должность, но 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); 
} 
+0

Вам не нужна проверка obj == null как null instanceof HudsonJob всегда false. –

+0

Как насчет добавления toString() в класс HudsonJob, который возвращает 'this.name'. Таким образом, содержащий метод list ищет «AnExistingJOB» .equals (hudsonjob) -> строка hudsonjob для строки возвращает то же, что и я, проверяя выше, и возвращает true. – srinannapa

4

Вы тормоз the contract для equals метода. Например:
Он симметричен: для любых ненулевых опорных значений x и y x.equals (y) должен возвращать true тогда и только тогда, когда y.equals (x) возвращает true.
И в вашем случае job.equals(string) может быть правдой, но string.equals(job) всегда будет ложным.

А что, вероятно, происходит в вашем списке является то, что элементы сравниваются с другой стороны:

for (Object el : list) { 
    if (parameter.equals(el)) { 
     ... 
    } 
} 

Это техническая причина, почему она не работает: "AnExistingJOB".equals(jobObject) всегда ложно.

редактировать
BTW, ваш метод hashCode тоже неправильно. Если вы сравниваете метод equals, вы игнорируете регистр, игнорируете его и в hashCode. Совет Bozho, вероятно, хороший: IDE будет генерировать эти методы лучше.Кроме того, вы можете проверить ответ Andreas_D на правильную реализацию.

Смежные вопросы