问题描述
我们需要比较具有一些共同字段的不同对象的 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.
编辑:您的第二个问题非常依赖于您进一步实施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
列表中.
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 数组列表并将匹配的行添加到新列表中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!