我们需要比较具有一些公共字段的不同对象的2个arraylists,然后将匹配的行存储到新的arraylist。我已经寻找解决方案,但无法得到我需要的东西。
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循环中进行吗?有人请吗?
答案 0 :(得分:2)
如果您实施等于比较问题的值,则可以使用contains
查看对象是否在其他列表中。
否则,您将不得不手动迭代列表,并检查每个对象。
如果您使用jdk8 Lambda,您可以执行类似的操作(编译并运行btw,使用正确的jdk):
public static void main(String args[]) throws ParseException {
TransformService transformService = (inputs1, inputs2) -> {
Collection<String> results = new ArrayList<>();
for (String str : inputs1) {
if (inputs2.contains(str)) {
results.add(str);
}
}
return results;
};
Collection<String> inputs1 = new ArrayList<String>(3) {{
add("lemon");
add("cheese");
add("orange");
}};
Collection<String> inputs2 = new
ArrayList<String>(3) {{
add("apple");
add("random");
add("cheese");
}};
Collection<String> results = transformService.transform(inputs1, inputs2);
for (String result : results) {
System.out.println(result);
}
}
public interface TransformService {
Collection<String> transform(Collection<String> inputs1, Collection<String> inputs2);
}
答案 1 :(得分:2)
由于我没有看到它们扩展的任何超类,因此您必须手动遍历列表。我假设了很多,例如你有属性的getter和setter,PersonNpi.name
或多或少与Person.firstname + Person.lastname
相同,你在Address
中有一些函数,如{ {1}},您的boolean checkEquality(String street1, String street2, String city, String state, String zip)
班级有Person
方法与getName()
进行比较。在这种情况下,循环遍历第一个数组,并检查每个项目是否第二个具有与之相等的任何项目。
PersonNpi
同样,我做了很多假设,也就是你有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
,并相应地获取所需的信息。 / p>
您应该详细说明,使用超类,并使用PersonNpi
函数。换句话说,通过函数更轻松地比较contains()
和Person
。
修改:您的第二个问题非常重要,如果不是非常依赖于您对PersonNpi
,Employee
和Person
的进一步实施。现在,我再次假设您有一些方法可以验证PersonNpi
,Employee
和Person
之间的相等性。
我建议不要在一个循环中进行检查,因为你有两个PersonNpi
被运行。对于第一个ArrayLists
中的每个记录,都会运行PersonNpi
- 列表。所以可能发生的事情是在我们检查了所有内容之后,一些List
保持不匹配,并且一些Persons
保持不匹配,因为我们没有标记PersonNpis
和{{1}我们匹配了。
总之:为了方便起见,只需添加此部分:
Persons
此方法确实要求您为所有3个人类实现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);
这样的超类下面。在这种情况下,您可以将equals(Object)
变为Human
使用一个循环(3个人类需要Object ArrayList
方法):
ArrayList<Human>
解释:我们通过两个列表循环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
列表中。
Edit2 :如果由于某种原因无法编辑这些类,请创建3 包装类,如:
nonMatchedPerson
如果您选择使用此方法,请在循环中更改此行:
addAll
到此:
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;
}
中。
答案 2 :(得分:1)
这样的事情应该有效。它假定您可以从Employee
和Person
构建PersonNpi
。另外,既然你没有告诉Address
的结构,我会留给你写地址匹配逻辑。
public List<Employee> findCommonElements(List<Person> list1,
List<PersonNpi> list2)
{
List<Employee> common = new ArrayList<Employee>();
for (Person p1 : list1) {
PersonNpi p2 = find(list2, p1);
if (p2 != null) {
common.add(new Employee(p1, p2));
}
}
}
private PersonNpi find(List<PersonNpi> list, Person p) {
for (PersonNpi p2 : list) {
if (matches(p, p2)) {
return p2;
}
}
return null;
}
private boolean matches(Person p1, PersonNpi p2) {
return /* logic for comparing name and address info */;
}
这是O(n 2 )操作。通过按名称和地址对数组进行排序,可以大大提高速度。排序操作是O(n log(n)),然后可以将比较实现为O(n)操作。
答案 3 :(得分:-2)
使用HashMap
存储第一个列表PersonNpiList
。使用map.get(Person) == null
检查此人是否在哈希映射中。