检查arraylist是否包含具有属性的对象

时间:2017-09-27 09:55:47

标签: java

我正在尝试使用方法来检查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;
}

4 个答案:

答案 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#containsdocumentation)方法使用Person#equals的结果来确定列表中的元素是否与参数相同。如果您没有实现此方法,则搜索Person的继承树中的方法。由于每个对象都继承自班级Object,如果在Object#equals的途中没有班级实施Object,您将回到equalsdocumentation)。但是,此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的回答中所示)

实现equals和hashCode,使用indexOf

现在我们让列表使用List#indexOfdocumentation)来完成迭代和匹配部分。这种方法与containsdocumentation)类似,但我们也希望获取元素,而不仅仅是检查它是否存在。

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答案中所见)

Compact Java 8解决方案

如果你有 Java 8 ,你可能更喜欢非常紧凑的变体。因此,我们使用Stream#filterdocumentation)根据方法返回truefalse(所谓的Predicate({{}来过滤流的元素3}}))。所以我们只需要对那里的名称进行检查并完成。

public Person lookupPerson(String personName) {
    return list.stream()
        .filter(p -> p.name.equals(personName))
        .findAny();
}

(如@GaneshToni的回答中所示)