我正在尝试使用方法来检查arraylist是否包含具有属性的对象。
public class Network {
// this variable is instantiated and set by the constructor
private ArrayList<Person> persons;
/**
* Constructor for objects of class Network
*/
public Network() {
// initialize instance variables
persons = new ArrayList<>();
persons.add(new Person("name1"));
persons.add(new Person("name2"));
}
这就是我现在所拥有的,但我无法让它发挥作用。
public Person lookupPerson(String personName) {
boolean personContain = persons.contains(new Person(personName));
if (personContain == true) {
System.out.println("ye");
} else {
System.out.println("nah");
}
return null;
}
答案 0 :(得分:6)
阅读ArrayList.contains
doc。
如果此collection包含指定的元素,则返回true。更正式地,当且仅当此集合包含至少一个元素e时才返回true(o == null?e == null:o.equals(e))。
它会使用参数 equals
方法,是否在Person
中定义?可能不是这样,它会使用Object.equals
来检查引用,而不是实例内容。
创建类似
的方法class Person {
...
@Override
public boolean equals(Object o){
if(o instanceof Person){
Person p = (Person) o;
return this.name.equals(p.getName());
} else
return false;
}
}
答案 1 :(得分:0)
如果您使用的是Java 8,则使用谓词。在谓词中,您可以使用给定的条件过滤arraylist,然后检查结果的arraylist大小是否为零。因此你可以找到具有prooerty的对象。
答案 2 :(得分:0)
如果以下行添加名为“name1”属性的人物对象
persons.add(new Person("name1"));
然后你可以使用@codematrix建议如果你使用的是java 8,或者你可以像这样使用它 而不是这一行
boolean personContain = persons.contains((personName));
你可以使用
public Person lookupPerson(String personName) {
boolean personContain =false;
for(person per : persons){
if(per.getName().equals(personName)){
//you can return person Object as below
//return per;
personContain =true;
}
}
答案 3 :(得分:0)
您的方法无效的原因是List#contains
(documentation)方法使用Person#equals
的结果来确定列表中的元素是否与参数相同。如果您没有实现此方法,则搜索Person
的继承树中的方法。由于每个对象都继承自班级Object
,如果在Object#equals
的途中没有班级实施Object
,您将回到equals
(documentation)。但是,此Object#equals
方法通过标识(放置在内存中)来对象对象。这意味着如果您创建一个具有相同属性的对象(例如 name 等),它将只是一个副本,但与列表中的每个标识不同。
请注意,此主题的StackOverflow有很多问题。如果你不熟悉它,你应该检查一下。以下是更详细地解释它的示例:What issues should be considered when overriding equals and hashCode in Java?
有多种方法可以解决这个问题。 让我们首先考虑一种非常简单易行的方法。
我们手动迭代列表并检查有关相关参数的每个条目。
public Person lookupPerson(String personName) {
for (final Person person : persons) {
// Access properties of person, usage of getter methods would be good
if (person.name.equals(personName)) {
// Found matching person
return person;
}
}
// Traversed whole list but did not find a matching person
return null;
}
(如@DeepakS的回答中所示)
现在我们让列表使用List#indexOf
(documentation)来完成迭代和匹配部分。这种方法与contains
(documentation)类似,但我们也希望获取元素,而不仅仅是检查它是否存在。
public class Person {
...
@Override
public boolean equals(final Object o) {
if (o == null) {
return false;
}
if (!(o instanceof Person)) {
return false;
}
if (o == this) {
return true;
}
final Person other = (Person) o;
return other.name.equals(this.name);
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result;
if (this.name != null) {
result += this.name.hashCode();
}
return result;
}
}
查找方法:
public Person lookupPerson(String personName) {
// The needle to search for
final Person needle = new Person(personName);
// The needle will now be equals to list objects
// regarding its equals method which only checks
// for the name
final int index = persons.indexOf(needle);
if (index != -1) {
// Get the element at this position
return persons.get(index);
} else {
return null;
}
}
(如@AxelH答案中所见)
如果你有 Java 8 ,你可能更喜欢非常紧凑的变体。因此,我们使用Stream#filter
(documentation)根据方法返回true
或false
(所谓的Predicate
({{}来过滤流的元素3}}))。所以我们只需要对那里的名称进行检查并完成。
public Person lookupPerson(String personName) {
return list.stream()
.filter(p -> p.name.equals(personName))
.findAny();
}
(如@GaneshToni的回答中所示)