当重写equals方法时,使用java Collection<E>.contains(Object o)方法

4

我有一个 List<Person> 对象,其中 Person 的定义如下:

public Person {
    private firstName;
    private lastName;
    //getter and setter methods
    public boolean equals(Object obj) {
        return lastName.equals(obj.toString());
    }
}

现在,我想查看这个 List<Person> 是否包含特定的姓氏。
if(myList.contains("Smith"))
    System.out.println("yay!");

然而,contains方法的定义是当(o==null ? e==null : o.equals(e))成立时返回true。因此,在此实例中,它使用了String.equals(Person)而不是Person.equals(String)。有没有简单的方法可以解决这个问题,或者我必须编写自己的逻辑来实现contains方法?
5个回答

3

有没有一种简单的方法来解决这个问题...

不可以,不能使用Collection.contains

根据equals的契约,实现必须是对称的:

对于任何非空引用值xyx.equals(y)应该返回true当且仅当y.equals(x)返回true

这意味着,对于somePerson.equals(someString)不返回false以外的任何其他结果都是直接违反了契约。

...或者我必须编写自己的contains逻辑吗?

是的。使用for循环:

for (Person p : myList)
    if (p.getLastName().equals("Smith"))
        return true;
return false;

或者,如果您正在使用Java 8,

return myList.stream().anyMatch(p -> p.getLastName().equals("Smith"));

2

一种方法是使用现有的 myList 构建一个 List<String> 视图并继续操作。

final List<Person> myList = yourList;
List<String> strView = new AbstractList<String>() { 
                    String get(int i) {
                             return myList.get(i).getLastName(); 
                       } 
                     int size() { return myList.size(); }
                  };

if(strView.contains("Smith")) System.out.println("Yaay");

1

你需要自己编写这个逻辑。

我强烈建议,当你重写equals方法时,遵循Java Object#equals定义的API。equals方法在许多地方使用(例如哈希映射),使用不同的逻辑将会在以后给你带来很多麻烦。


0

这里的另一个选择是使用Guava的Iterables.any

 Predicate<Person> findMe(final String name){
    return new Predicate<Person>(){
        public boolean apply(Person input){
            return input.lastname.equals(name);
        }
    }
 }

 boolean contains = Iterables.any(myList, findMe("Smith"));

或者

Function<Person, String> lastName = new Function<Person, String>(){
     public String apply(Person input){
        return input.lastName;
     }
}

boolean contains = Lists.transform(myList, lastName).contains("Smith");

0

由于您不是在寻找一个Person,最好的沟通解决方案是拥有一个明确指出正在寻找姓氏的方法,例如containsLastName或其他方法,或者使用一个示例Person作为类似条件的对象。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接