我有一个List< 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)。有没有一种简单的方法来解决这个问题,还是我必须为包含?编写自己的逻辑?
答案 0 :(得分:3)
有没有一种简单的方法来解决这个问题......
不,不使用Collection.contains
。
根据equals
的合同,实施必须对称:
对于任何非空引用值
x
和y
,当{且仅x.equals(y)
返回{{1}时,true
应返回y.equals(x)
}} 的
这意味着返回true
false
以外的任何其他内容都是违反合同的行为。
...或者我是否必须为包含自己的逻辑?
是。使用for循环:
somePerson.equals(someString)
或者,如果您使用的是Java 8,
for (Person p : myList)
if (p.getLastName().equals("Smith"))
return true;
return false;
答案 1 :(得分: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");
答案 2 :(得分:1)
你必须为此编写自己的逻辑。
我强烈建议您在覆盖equals方法时,坚持使用java Object#equals定义的API。 equals方法在很多地方使用(hashmaps命名为1),使用不同的逻辑会让你以后遇到很多麻烦。
答案 3 :(得分:0)
由于您没有寻找Person
,因此最具沟通性的解决方案是使用一种方法明确指出它正在寻找姓氏,例如containsLastName
或其他什么,或者举个例子{ {1}}并将其用作类似标准的对象。
答案 4 :(得分: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");