【问题标题】:Finding equal objects using equals method in Java在Java中使用equals方法查找相等的对象
【发布时间】:2020-02-12 19:23:00
【问题描述】:

我有一个对象列表,其中包含名称、地址 line1、地址 line2、城市、listOfPeopleMatched 属性。我通过覆盖 equals 和 hashcode 方法找到基于地址 line1、地址 line2 和城市(不是名称)的相等性。现在我想获取对象匹配的人的姓名并将它们存储在 listOfPeopleMatched 中。例如:[["Val","Ashish"], ["Steve","Alex"]]。这怎么能只在equals方法中完成?

public class Person {

    private String name;
    private String addressLine1;
    private String addressLine2;
    private String city;
    private List<List<String>> listOfPeopleMatched = 
                                 new ArrayList<List<String>>();

    public String getName() {
        return name;
    }

    public List<List<String>> getListOfPeopleMatched() {
        return listOfPeopleMatched;
    }

    public void setListOfPeopleMatched(List<List<String>> listOfPeopleMatched) {
        this.listOfPeopleMatched = listOfPeopleMatched;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAddressLine1() {
        return addressLine1;
    }

    public void setAddressLine1(String addressLine1) {
        this.addressLine1 = addressLine1;
    }

    public String getAddressLine2() {
        return addressLine2;
    }

    public void setAddressLine2(String addressLine2) {
        this.addressLine2 = addressLine2;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public Person(String name, String addressLine1, 
            String addressLine2, String city) {
        super();
        this.name = name;
        this.addressLine1 = addressLine1;
        this.addressLine2 = addressLine2;
        this.city = city;
    }

    @Override
    public String toString() {
        return "Person [name=" + name + 
                        ", addressLine1=" + 
                        addressLine1 + ", addressLine2=" + 
                        addressLine2 + ", city="
                + city + "]";
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((addressLine1 == null) ? 
                0 : addressLine1.hashCode());
        result = prime * result + ((addressLine2 == null) ? 
                0 : addressLine2.hashCode());
        result = prime * result + ((city == null) ? 
                0 : city.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Person other = (Person) obj;
        if (addressLine1 == null) {
            if (other.addressLine1 != null)
                return false;
        } else if (!addressLine1.equals(other.addressLine1))
            return false;
        if (addressLine2 == null) {
            if (other.addressLine2 != null)
                return false;
        } else if (!addressLine2.equals(other.addressLine2))
            return false;
        if (city == null) {
            if (other.city != null)
                return false;
        } else if (!city.equals(other.city))
            return false;
        return true;
    }
}

Person person1 = new Person("Val", "ABC", "Shivaji Nagar", "Pune");
Person person2 = new Person("Ashish", "ABC", "Shivaji Nagar", "Pune");
Person person3 = new Person("Steve", "MNO", "Shivaji Nagar", "Pune");
Person person4 = new Person("Alex", "MNO", "Shivaji Nagar", "Pune");

Set<Person> uniquePeople = new HashSet<>();
uniquePeople.add(person1);
uniquePeople.add(person2);
uniquePeople.add(person3);
uniquePeople.add(person4);

System.out.println(uniquePeople);

【问题讨论】:

  • 不确定您在问什么 - 您想要set 的密钥吗?
  • 因为 person1 和 person2 只有一个条目(因为它们基于等号和哈希码是相等的),我希望他们的名字存储在 listOfPeopleMatched 中。
  • 只是猜测,但无法添加到equals 方法中的列表中?
  • 所以我认为这里的正确方法是在每个 Person 上都有一个 Address 对象并应用 equals 方法。
  • 您能否详细说明一下,因为我想不出它是如何解决这个问题的。可能带有一些示例代码。

标签: java equals hashcode


【解决方案1】:

我认为您想将您的地址数据封装在一个对象中。这样一个 Person 不等于它的地址,您可以进行更精细的搜索。另外,您以这种方式分离关注点。

我在这里写了一个工作示例:

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

public class Person {

    public static void main(String[] args) {


        // what we're searching for
        Address address = new Address("123 N 3rd st", "east ohg", "this-city");

        // init
        List<Person> persons = new ArrayList<>();
        persons.add(new Person("Jim", "123 N 56 st", "east ohg", "this-city"));
        persons.add(new Person("Kyle", "145 N 67th st", "east ohg", "this-city"));
        persons.add(new Person("Sam", "12 beach av", "east ohg", "this-city"));
        persons.add(new Person("Tracy", "123 N 3rd st", "east ohg", "this-city"));
        persons.add(new Person("Ashley", "123 N 3rd st", "east ohg", "this-city"));


        // search
        List<Person> people = persons.stream().filter(person -> person.address.equals(address)).collect(Collectors.toList());

        people.forEach(System.out::println);


    }

    String name;
    Address address;

    public Person(String name,
                  String addressLine1,
                  String addressLine2,
                  String city) {
        this.name = name;
        this.address = new Address(addressLine1,
                                   addressLine2,
                                   city);
    }

    private static final class Address {
        String addressLine1;
        String addressLine2;
        String city;


        public Address(String addressLine1, String addressLine2, String city) {
            this.addressLine1 = addressLine1;
            this.addressLine2 = addressLine2;
            this.city = city;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Address address = (Address) o;
            return Objects.equals(addressLine1, address.addressLine1) &&
                   Objects.equals(addressLine2, address.addressLine2) &&
                   Objects.equals(city, address.city);
        }

        @Override
        public int hashCode() {
            return Objects.hash(addressLine1, addressLine2, city);
        }


        @Override
        public String toString() {
            return "Address{" +
                   "addressLine1='" + addressLine1 + '\'' +
                   ", addressLine2='" + addressLine2 + '\'' +
                   ", city='" + city + '\'' +
                   '}';
        }
    }


    @Override
    public String toString() {
        return "Person{" +
               "name='" + name + '\'' +
               ", address=" + address +
               '}';
    }
}

【讨论】:

  • 我想将其对象匹配的所有名称存储在列表中。我没有将它与任何特定的地址详细信息进行比较。我已经更新了我的代码并添加了一个人对象和我期望的输出。
猜你喜欢
  • 2013-10-27
  • 2020-11-06
  • 2011-04-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-20
  • 1970-01-01
相关资源
最近更新 更多