本文介绍了比较不同对象的 2 个 Java 数组列表并将匹配的行添加到新列表中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们需要比较具有一些共同字段的不同对象的 2 个数组列表,然后将匹配的行存储到一个新的数组列表中.我已经搜索了解决方案,但无法获得我需要的东西.

We need to compare 2 arraylists of different objects having some common fields, and then store the matching rows to a new arraylist. I have searched for solutions, but wasn't able to get what I need.

List<Person> personList = new ArrayList<Person>();
Person:
private String firstName;
    private String lastName;
    private String street1;
    private String street2;
    private String city;
    private String stateCode;
    private String zipCode;

List<PersonNpi> npiList = new ArrayList<PersonNpi>();
PersonNpi:
private String name;
    private String npi;
    private Address address;

所以我需要检查 name &将PersonNpiList中PersonNpi对象中的地址与PersonList中的Person对象匹配,如果匹配,则将Person details + Npi保存到新的Arraylist

So I need to check if the name & address in the PersonNpi object in the PersonNpiList match to a Person object in the PersonList, and if yes save the Person details + Npi to a new Arraylist<Employee>

希望我对这个问题很清楚.请让我知道如何有效地解决这个问题.

Hope I'm clear on the question. Please let me know on how to solve this efficiently.

谢谢

哈利

我需要将不匹配的行(在第一个数组列表上)保存到另一个列表中.我需要有另一个循环还是可以在同一个 For 循环上执行?请问有人吗?

推荐答案

由于我没有看到它们扩展的任何超类,因此您必须手动遍历列表.我假设了很多,例如你的属性有 getter 和 setter,PersonNpi.name 或多或少与 Person.firstname + Person.lastname 相同,您在 Address 中有一些函数,例如 boolean checkEquality(String street1, String street2, String city, String state, String zip),您的 Person 类有一个 getName() 方法来与 PersonNpis 进行比较.在这种情况下,循环遍历第一个数组,并检查每个元素是否与第二个元素相等.

Since I don't see any superclasses from which they extend, you have to manually iterate through your lists. I am assuming a lot, for instance that you have getters and setters for your attributes, that PersonNpi.name is more or less the same as Person.firstname + Person.lastname, that you have some function in Address like boolean checkEquality(String street1, String street2, String city, String state, String zip), that your Person class has a getName() method to compare with PersonNpis. In that case, loop through the first array, and check for every item if the second has anything equal to it.

ArrayList<Employee> employees = new ArrayList<Employee>();
for(Person person : personList) {
  for(PersonNpi personNpi : npiList) {
    if (person.getName().equals(personNpi.getName()) &&
        person.getAddress().checkEquality(...address parts here...)) {
      employees.add(new Employee(person, personNpi));
    }
  }
}

同样,我做了很多假设,还有一个假设你有一个 Employee 构造函数,它只需要 PersonPersonNpi, 并相应地获取所需信息.

Again, I made a lot of assumptions, also the one that you have an Employee constructor which just requires the Person and the PersonNpi, and gets the required information accordingly.

您应该详细说明,使用超类,并使用 contains() 函数.换句话说,通过函数可以更容易地比较 PersonPersonNpi.

You should elaborate more, use superclasses, and use the contains() function. In other words, make comparing the Person and the PersonNpi easier through a function.

编辑:您的第二个问题非常依赖于您进一步实施EmployeePersonPersonNpi.现在,我将再次假设您有一些方法可以验证 EmployeePersonPersonNpi 之间的相等性.

Edit: your second question is highly, if not extremely dependant on your further implementation of Employee, Person and PersonNpi. For now, I'll yet again assume you have some methods that verify equality between Employee, Person and PersonNpi.

我建议不要在一个循环中进行检查,因为您有两个 ArrayLists 已运行.PersonNpi-list 针对第一个 List 中的每条记录运行.所以可能会发生的情况是在我们检查完所有内容之后,一些 Persons 没有匹配,还有一些 PersonNpis 没有匹配,因为我们没有标记哪些 PersonsPersonNpis 我们已经匹配了.

I'd suggest to not do the checking in one loop, since you have two ArrayLists which are ran through. The PersonNpi-list is ran through for every record in the first List. So what might happen is after we checked everything, a few Persons are left unmatched, and a few PersonNpis are left unmatched, since we don't flag which Persons and PersonNpis we've matched.

结论:为了方便起见,只添加这部分:

In conclusion: for easiness' sake, just add this part:

ArrayList<Object> nonMatchedPersons = new ArrayList<Object>();
for (Person person : personList)
    if (!employees.contains(person))
        nonMatchedPersons.add(person);
for (PersonNpi personNpi : npiList)
    if (!employees.contains(personNpi))
        nonMatchedPersons.add(personNpi);

此方法确实要求您为所有 3 个人员类实现 equals(Object) 方法,您可以考虑将其置于像 Human 这样的超类之下.在这种情况下,您可以将 Object ArrayList 变成 ArrayList

This method does require you to implement the equals(Object) method for all 3 person classes, which you might consider putting beneath a superclass like Human. In that case, you can make the Object ArrayList into a ArrayList<Human>

使用一个循环(需要 equals(Object) 方法用于 3 个人员类):

With one loop (requires equals(Object) method for the 3 person classes):

List<Employee> employees = new ArrayList<Employee>();
ArrayList<Object> nonMatchedPersons = new ArrayList<Object>();

Iterator<Person> personIterator = personList.iterator();
while (personIterator.hasNext()) {
    Iterator<PersonNpi> npiIterator = npiList.iterator();
    while(npiIterator.hasNext()) {
        Person person = personIterator.next();
        PersonNpi personNpi = npiIterator.next();
        if (person.equals(personNpi)) {
            employees.add(new Employee(person, personNpi));
            personIterator.remove();
            npiIterator.remove();
        }
    }
}

nonMatchedPersons.addAll(personList);
nonMatchedPersons.addAll(npiList);

说明:我们使用 Iterators 循环遍历两个列表,使我们能够在迭代时从列表中删除.所以在 personListnpiList 中,只剩下单打,因为我们将双打添加到 Employee-list,立即将它们从另一个列表中删除两个清单.我们使用 addAll 方法将两个列表中剩余的单身人士添加到我们的 nonMatchedPerson 列表中.

Explanation: we loop with Iterators through both lists, to enable us to remove from the list while iterating. So in the personList and the npiList, only the singles remain, as we add doubles to the Employee-list, instantly removing them from the other two lists. We add the remaining singles in the two lists to our nonMatchedPerson-list with the addAll method.

Edit2:如果由于某种原因您无法编辑这些类,请制作 3 个 wrapper 类,例如:

Edit2: If you can't edit those classes for whatever reason, make 3 wrapper classes, something like:

public class PersonWrapper {
    private Person person;

    public PersonWrapper(Person person) {
        this.person = person;
    }

    @override
    public boolean equals(Object other) {
        if (other == null)
            return false;
        if (other instanceof PersonWrapper) {
            //etc etc, check for equality with other wrappers.
            ...
        }
    }
}

如果您选择使用这种方法,请更改循环中的这一行:

If you choose to use this approach, change this line in the loop:

if (person.equals(personNpi)) {

为此:

if (new PersonWrapper(person).equals(new PersonNpiWrapper(personNpi))) {

使用它,您仍然可以实现自己的 equals() 方法.

Using this, you can still implement your own equals() method.

另一种解决方案可能是您创建一个像这样的静态方法:

Another solution could be that you make a static method like this:

public static boolean equals(Object this, Object that) {
    if (this instanceof Person || this instanceof PersonNpi) //et cetera, et cetera
        return true;
    return false;
}

现在只需调用 Person.equals(person, personNpi),假设您将该方法放在 Person 类中.

Now just call Person.equals(person, personNpi), assuming you put the method in the class Person.

这篇关于比较不同对象的 2 个 Java 数组列表并将匹配的行添加到新列表中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-06 23:15