如何通过比较Java中给定对象中的字段值来合并两个对象列表
我有两个对象列表,我想把它们合并成一个。对象有两个字段,“名称”和“值”。对于列表2中的给定obj2,如果我们在列表1中找到obj1的“名称”字段匹配项(列表1中的obj1和列表2中的obj2),则我们使用obj2的“值”覆盖obj1。如果没有找到匹配项,则将obj2添加到列表1中。最终输出将更新为列表1 有什么快速的方法可以做到这一点吗?我所能想到的就是使用两个for循环来比较两个列表中的所有对象如何通过比较Java中给定对象中的字段值来合并两个对象列表,java,arraylist,merge,Java,Arraylist,Merge,我有两个对象列表,我想把它们合并成一个。对象有两个字段,“名称”和“值”。对于列表2中的给定obj2,如果我们在列表1中找到obj1的“名称”字段匹配项(列表1中的obj1和列表2中的obj2),则我们使用obj2的“值”覆盖obj1。如果没有找到匹配项,则将obj2添加到列表1中。最终输出将更新为列表1 有什么快速的方法可以做到这一点吗?我所能想到的就是使用两个for循环来比较两个列表中的所有对象 class NameValueObj{ String name; String value; }
class NameValueObj{
String name;
String value;
}
List<NameValueObj> merge(List<NameValueObj> list1, List<NameValueObj> list2){
// I want to merge two list here
}
类名称值obj{
字符串名;
字符串值;
}
列表合并(列表1、列表2){
//我想在这里合并两个列表
}
NameValueObj是一个给定的,所以我可以;不要修改对象源
这是我的方法
private List<Header> mergeHeaders(List<Header> defHeaders, List<Header> ovrdHeaders) {
List<Header> lFinal = defHeaders;
boolean foundMatch = false;
for (Header ovrdHeader : ovrdHeaders) {
foundMatch = false;
for (Header defHeader : defHeaders) {
if (defHeader.getName().equalsIgnoreCase(ovrdHeader.getName())) {
defHeader.setValue(ovrdHeader.getValue());
foundMatch = true;
break;
}
}
if(!foundMatch) {
lFinal.add(ovrdHeader);
}
}
return lFinal;
}
private List mergeHeaders(List defHeaders,List ovrdHeaders){
List lFinal=defHeaders;
布尔foundMatch=false;
for(标头ovrdHeader:ovrdHeaders){
foundMatch=false;
对于(标题defHeader:defHeaders){
if(defHeader.getName().equalsIgnoreCase(ovrdHeader.getName())){
setValue(ovrdHeader.getValue());
foundMatch=true;
打破
}
}
如果(!foundMatch){
l最终添加(ovrdHeader);
}
}
返回lFinal;
}
标头具有名称和值字段。标题在给定的列表中具有唯一的名称。因此,如果您看到主要的效率开销,您的方法是搜索另一个列表中的特定元素。因此,您应该问,如何有效地在另一个列表中搜索对象
- 数组(如果您知道索引)
- HashMap(如果您知道密钥)
O(n*n)
(二次型)
您可以在O(n)
(线性)中使用临时LinkedHashMap
:
private List<Header> mergeHeaders(final List<Header> defHeaders, final List<Header> ovrdHeaders) {
final Map<String, Header> headersMap = new LinkedHashMap<String, Header>();
for (final Header defHeader : defHeaders) {
headersMap.put(defHeader.getName().toLowerCase(), defHeader);
}
for (final Header ovrdHeader : ovrdHeaders) {
headersMap.put(ovrdHeader.getName().toLowerCase(), ovrdHeader);
}
return new ArrayList<Header>(headersMap.values());
}
如果标题名称不唯一,此实现将保留列表1或列表2中的最后一个标题
- 我不得不解决一个类似的问题。在我的例子中,当哈希映射已经有或没有一个项时,我必须创建自定义决策规则。以下是我的最终解决方案:
辅助类:
公共接口合并规则{
T olderListContains(T olderObj,T newObj);
T olderListNotContains(T newObj);
}
公共抽象类HashAbstract{
公共字符串getKey(){
返回null;
}
}
我的最终合并方法:
公共静态列表合并(最终列表旧列表,
最终名单新名单,
合并规则(合并规则){
final Map listMap=新建LinkedHashMap();
用于(最后一个T olderObj:olderList){
put(((HashAbstract)olderObj.getKey(),olderObj);
}
对于(最终T newObj:newList){
字符串newObjKey=((HashAbstract)newObj.getKey();
T返回obj;
if(listMap.containsKey(newObjKey)){
returnObj=mergeRules.olderListContains(listMap.get(newObjKey),newObj);
}否则{
returnObj=mergeRules.olderListNotContains(newObj);
}
put(newObjKey,returnObj);
}
返回新的ArrayList(listMap.values());
}
例如:
class NameValueObj扩展了HashAbstract{
公共字符串名称;
公共字符串值;
@凌驾
公共字符串getKey(){
返回name.trim().toUpperCase();
}
}
NameValueObj obj1=新的NameValueObj();
obj1.name=“测试”;
obj1.value=“1234”;
NameValueObj obj2=新的NameValueObj();
obj2.name=“testSomething”;
obj2.value=“4321”;
NameValueObj obj3=新的NameValueObj();//将更新的obj
obj3.name=“测试”;
obj3.value=“1212”;
NameValueObj obj4=新的NameValueObj();//新对象
obj4.name=“testObj”;
obj4.value=“1313”;
List list1=新的ArrayList();
列表1.添加(obj1);
列表2.add(obj2);
List list2=新的ArrayList();
清单2.添加(obj3);
清单2.添加(obj4);
List mergedList=merge(列表1、列表2、,
新的Compare.MergeRules(){
@凌驾
public NameValueObj olderListContains(NameValueObj olderObj,NameValueObj newObj){
return newObj;//如果obj已经存在,则返回新的
}
@凌驾
public NameValueObj olderListNotContains(NameValueObj newObj){
return newObj;//如果不存在,则返回新的obj
}
});
示例的mergedList
:
name: test - value: 1212
name: testSomething - value: 4321
name: testObj - value: 1313
谢谢你的解释。此算法速度快得多,但如果第二个列表中的项与第一个列表中的项具有相同的名称但值不同,则它无法解决“匹配场景”。它不会用此新项覆盖第一个列表。
name: test - value: 1212
name: testSomething - value: 4321
name: testObj - value: 1313