比较2个不同对象的Java数组列表,并将匹配的行添加到新列表中 [英] Compare 2 Java arraylists of different objects and add the matching rows to a new List
问题描述
我们需要比较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.name
与Person.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
构造函数,只需要Person
和PersonNpi
,并相应地获取了所需的信息.
您应该详细说明,使用超类并使用contains()
函数.换句话说,通过函数可以比较Person
和PersonNpi
.
编辑:您的第二个问题非常重要,即使不是非常依赖于您对Employee
,Person
和PersonNpi
的进一步实现.现在,我再次假设您有一些方法可以验证Employee
,Person
和PersonNpi
之间的相等性.
我建议不要在一个循环中进行检查,因为您有两个正在运行的ArrayLists
.对于第一个List
中的每个记录,都会运行PersonNpi
-list.所以可能发生的事情是,在我们检查了所有内容之后,有几个Persons
不匹配,而有几个PersonNpis
不匹配,因为我们没有标记我们已经匹配了哪个Persons
和PersonNpis
.>
结论:为简便起见,只需添加以下部分:
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
,以使我们能够在迭代时从列表中删除.因此,在personList
和npiList
中,当我们将双打添加到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 PersonNpi
s. 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屋!