问题描述
我们需要比较 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()
方法来与 PersonNpi
s 进行比较.在这种情况下,循环遍历第一个数组,并检查第二个数组中的每个元素是否与它相等.
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));
}
}
}
再一次,我做了很多假设,你也有一个 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.
您应该详细说明,使用超类,并使用 contains()
函数.换句话说,通过函数比较Person
和PersonNpi
更容易.
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:您的第二个问题非常依赖于您对 Employee
、Person
和 PersonNpi代码>.现在,我再次假设您有一些方法可以验证
Employee
、Person
和 PersonNpi
之间的相等性.
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
未匹配,因为我们没有标记哪个 Persons
和 PersonNpis
我们已经匹配.
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
循环遍历两个列表,以使我们能够在迭代时从列表中删除.所以在 personList
和 npiList
中,只剩下单打,因为我们将双打添加到 Employee
-list,立即将它们从另一个中删除两个列表.我们使用 addAll
方法将两个列表中剩余的单曲添加到我们的 nonMatchedPerson
-list 中.
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 数组列表并将匹配的行添加到新列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!