简体   繁体   English

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

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

I have two list of objects and I want to merge them into one. 我有两个对象列表,我想将它们合并为一个。 the objects have two fields, "name" and "value". 对象有两个字段,“名称”和“值”。 For a given obj2 in list2 , if we find a match of "name" field of obj1 in list1 (obj1 from list1 and obj2 from list2), then we use the "value" of the obj2 to overwrite obj1. 对于list2中给定的obj2,如果我们在list1中找到obj1的“name”字段匹配(list1中的obj1和list2中的obj2),那么我们使用obj2的“value”来覆盖obj1。 if there is no match found, then we add obj2 to list1. 如果找不到匹配项,那么我们将obj2添加到list1。 The final output will be updated list1. 最终输出将更新list1。

Is there any fast way to do this? 有什么快速的方法可以做到这一点吗? All I can think of is to use two for loops to compare all the objects in two lists 我能想到的是使用两个for循环来比较两个列表中的所有对象

class NameValueObj{
String name;
String value;
}

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

NameValueObj is a given so I can;t modify the object source. NameValueObj是给定的,所以我可以修改对象源。

Here is my way of doing it. 这是我的方式。

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

Header has name and value field. 标题有名称和值字段。 Headers has unique names in a given list. 标题在给定列表中具有唯一名称。

Your algorithm is O(n*n) (quadratic). 你的算法是O(n*n) (二次)。

You can do it in O(n) (linear) using a temporary LinkedHashMap : 你可以使用临时的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());
}

Note that the behavior is NOT exactly the same as the behavior of your implementation. 请注意,该行为与您的实现行为并不完全相同 The differences are: 不同之处是:

  • This implementation returns a new list instance instead of modifying the first list. 此实现返回新的列表实例,而不是修改第一个列表。 IMO, it's a benefit, but it may depend. IMO,这是一个好处,但它可能取决于。 If needed, you can modify the first list as follows (though I'd not recommend that): 如果需要,您可以按如下方式修改第一个列表(虽然我建议这样做):

     defHeaders.clear(); defHeaders.addAll(headersMap.values()); return defHeaders; 
  • This implementation assumes that header names are already unique (case INsensitively) in both lists, while your one doesn't make this assumption. 此实现假定标题名称在两个列表中都是唯一的(不区分大小写),而您的标题名称不是这样的假设。
    If header names are not unique, this implementation would preserve the last header from list 1 or list 2. 如果标头名称唯一,则此实现将保留列表1或列表2中的最后一个标头。

So if you see the major efficiency overhead your way is searching for a particular element in another list. 因此,如果您看到主要的效率开销,那么您将在另一个列表中搜索特定元素。 So you should ask how can you efficiently search for the object in another list? 所以你应该问你如何有效地搜索另一个列表中的对象?

  • Array(if you know the index) 数组(如果您知道索引)
  • HashMap(if you kow the key) HashMap(如果您知道密钥)

HashMap looks like an easy way to implement your problem. HashMap看起来像是一种实现问题的简单方法。 So what you can do is iterate through your first list and add name as key and value as value in the map. 所以你可以做的是遍历你的第一个列表并在地图中添加名称作为键和值作为值。 Similarly for the second list. 类似地,第二个列表。

Next iterate through the keyset of 1st map and search for corresponding name key in 2nd list. 接下来遍历第一个映射的键集,并在第二个列表中搜索相应的名称键。 If found add as value in 1st list. 如果发现在第一个列表中添加为值。

The major drawback here is using extra data structures. 这里的主要缺点是使用额外的数据结构。

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

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