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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/46444855/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 09:13:00  来源:igfitidea点击:

Checking if arraylist contains an object with an attribute

java

提问by Awaythrows8

I'm trying to use a method to check if an arraylist contains an object with an attribute.

我正在尝试使用一种方法来检查数组列表是否包含具有属性的对象。

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"));
    }

This is what i have at the moment, but i cant get it to work.

这就是我目前所拥有的,但我无法让它工作。

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;
}

回答by AxelH

Read ArrayList.containsdoc.

阅读ArrayList.contains文档。

Returns true if this collection contains the specified element. More formally, returns true if and only if this collection contains at least one element e such that (o==null ? e==null : o.equals(e)).

如果此集合包含指定的元素,则返回 true。更正式地说,当且仅当此集合包含至少一个元素 e 使得 (o==null ? e==null : o.equals(e)) 时才返回 true。

It will use the parameterequalsmethod, is it defined in Person? Probably not so it will use Object.equalsthat will check the references, not instance content.

它将使用参数equals方法,是否在Person? 可能不是这样,它会使用Object.equals它来检查引用,而不是实例内容。

Create the method like

创建方法,如

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;
     }
}

回答by Zabuzard

The problem

问题

The reason why your approach did not work is because the List#contains(documentation) method uses the result of Person#equalsto decide if an element from the list is the same as the argument. If you have not implemented this method than it searches the method in the inheritance tree of Person. As every object inherits from the class Objectyou will fall back to Object#equals(documentation) if no class on the way to Objecthas implemented equals. However this Object#equalsmethod compairs objects by their identity(place in the memory). That means that if you create an object that has the same properties (like nameand so on) it just will be a copy but not the same as the one in the list, per identity.

您的方法不起作用的原因是List#contains文档)方法使用的结果Person#equals来决定列表中的元素是否与参数相同。如果您尚未实现此方法,则它会在 的继承树中搜索该方法Person。从类中的每个对象继承Object你会回落到Object#equals文件),如果在途中没有类Object已经实现equals。然而,此Object#equals方法通过对象的身份(在内存中的位置)来比较对象。这意味着如果您创建一个具有相同属性(如名称等)的对象,它只是一个副本,但与列表中的每个标识不同。

Note that there are many questions here at StackOverflow for this topic. If you're not familiar with it you should check it out. Here is an example explaining it in more detail: What issues should be considered when overriding equals and hashCode in Java?

请注意,在 StackOverflow 上有很多关于这个主题的问题。如果你不熟悉它,你应该检查一下。下面是一个更详细地解释它的示例:在 Java 中重写 equals 和 hashCode 时应考虑哪些问题?

There are multiple ways of solving this problem. Let's first consider a very straightforward and easy way.

有多种方法可以解决这个问题。让我们首先考虑一个非常直接和简单的方法。

Iterating manually

手动迭代

We manually iterate the list and check every entry regarding the relevant parameters.

我们手动迭代列表并检查有关相关参数的每个条目。

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;
}

(like seen in the answer of @DeepakS)

(就像在@DeepakS 的回答中看到的那样)

Implement equals and hashCode, use indexOf

实现equals和hashCode,使用indexOf

Now we let the list do the iterating and matching part by using List#indexOf(documentation). This approach is similar to yours with contains(documentation) but we would also like to get the element, not just check if its there or not.

现在我们让列表通过使用List#indexOf( documentation)来完成迭代和匹配部分。这种方法与您的contains文档)类似,但我们也想获取元素,而不仅仅是检查它是否存在。

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;
    }
}

And the lookup method:

和查找方法:

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;
    }
}

(like seen in the answer of @AxelH)

(就像在@AxelH 的回答中看到的那样)

Compact Java 8 solution

紧凑型 Java 8 解决方案

If you have Java 8you may prefer a very compact variant. Therefore we use Stream#filter(documentation) which filters elements of a stream based on if the method returns trueor false(a so called Predicate(documentation)). So we just need to implement a check for the namethere and are finished.

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

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

(like seen in the answer of @GaneshToni)

(就像在@GaneshToni 的回答中看到的那样)

回答by Ganesh Toni

If you are using Java 8 then use predicate. in predicte you can filter arraylist with given criteria and then check if the resultant arraylist size is zero or not. thus you can find object with prooerty is there or not.

如果您使用的是 Java 8,则使用谓词。在 predicte 中,您可以使用给定的条件过滤 arraylist,然后检查结果 arraylist 大小是否为零。因此,您可以找到具有证明的对象是否存在。

回答by Deepak S

if the below line is adding a person object with name "name1" attribute

如果下面这行添加了一个名为“name1”属性的人对象

 persons.add(new Person("name1")); 

then you can use @codematrix suggestion if you are using java 8 or u can use it like this instead of this line

那么你可以使用@codematrix 建议,如果你使用的是 java 8 或者你可以像这样使用它而不是这一行

boolean personContain = persons.contains((personName));

you can use

您可以使用

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;
  }
 }