繁体   English   中英

如何通过比较Java中给定对象中的字段值来合并两个对象列表

[英]How to merge two lists of objects by comparing field value in the given objects in Java

我有两个对象列表,我想将它们合并为一个。 对象有两个字段,“名称”和“值”。 对于list2中给定的obj2,如果我们在list1中找到obj1的“name”字段匹配(list1中的obj1和list2中的obj2),那么我们使用obj2的“value”来覆盖obj1。 如果找不到匹配项,那么我们将obj2添加到list1。 最终输出将更新list1。

有什么快速的方法可以做到这一点吗? 我能想到的是使用两个for循环来比较两个列表中的所有对象

class NameValueObj{
String name;
String value;
}

List<NameValueObj> merge(List<NameValueObj> list1, List<NameValueObj> list2){
// I want to merge two list here
}

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;
    }

标题有名称和值字段。 标题在给定列表中具有唯一名称。

你的算法是O(n*n) (二次)。

你可以使用临时的LinkedHashMapO(n) (线性)中完成它:

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());
}

请注意,该行为与您的实现行为并不完全相同 不同之处是:

  • 此实现返回新的列表实例,而不是修改第一个列表。 IMO,这是一个好处,但它可能取决于。 如果需要,您可以按如下方式修改第一个列表(虽然我建议这样做):

     defHeaders.clear(); defHeaders.addAll(headersMap.values()); return defHeaders; 
  • 此实现假定标题名称在两个列表中都是唯一的(不区分大小写),而您的标题名称不是这样的假设。
    如果标头名称唯一,则此实现将保留列表1或列表2中的最后一个标头。

因此,如果您看到主要的效率开销,那么您将在另一个列表中搜索特定元素。 所以你应该问你如何有效地搜索另一个列表中的对象?

  • 数组(如果您知道索引)
  • HashMap(如果您知道密钥)

HashMap看起来像是一种实现问题的简单方法。 所以你可以做的是遍历你的第一个列表并在地图中添加名称作为键和值作为值。 类似地,第二个列表。

接下来遍历第一个映射的键集,并在第二个列表中搜索相应的名称键。 如果发现在第一个列表中添加为值。

这里的主要缺点是使用额外的数据结构。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM