比较2个不同对象的Java数组列表,并将匹配的行添加到新列表中 [英] Compare 2 Java arraylists of different objects and add the matching rows to a new List

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

问题描述

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

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 & address in the PersonNpi object in the PersonNpiList match to a Person object in the PersonList,如果是,请保存Person details + Npi to a new Arraylist<Employee>

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

谢谢

哈里

我需要将不匹配的行(在第一个arraylist上)也保存到另一个列表中.我是否需要另一个循环,或者可以在同一个For循环中执行?有人吗?

解决方案

由于我没有看到扩展自其的任何超类,因此必须手动遍历列表.我假设很多东西,例如,您的属性具有getter和setter,PersonNpi.namePerson.firstname + Person.lastname大致相同,在Address中具有某些功能,例如boolean checkEquality(String street1, String street2, String city, String state, String zip),而您的Person类具有与PersonNpi进行比较的getName()方法.在这种情况下,请循环遍历第一个数组,并检查第二个数组是否具有与其相等的所有内容.

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,并相应地获取了所需的信息.

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

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

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

结论:为简便起见,只需添加以下部分:

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<Human>

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

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-列表时,仅保留了单打,立即将它们从其他两个列表中删除.我们使用addAll方法将两个列表中的剩余单曲添加到nonMatchedPerson-列表中.

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

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 (person.equals(personNpi)) {

对此:

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

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

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

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

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

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;

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.

Thanks

Harry

EDIT:

I need to save the non-matching rows (on the first arraylist) as well to another list. Do I need to have another loop or can I do it on the same For loop? Anyone please?

解决方案

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

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.

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.

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.

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

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>

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

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: 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)) {

to this:

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

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

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

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

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆