用唯一键合并三个HashMap <string,pojo =“”>

时间:2018-08-06 04:45:57

标签: java collections

我有3个此通用类型HashMap<String,Server>的HashMap,但是我想根据自己的唯一键合并所有HashMap的数据。但是只有Server pojo具有不同的数据。

因此,第一个哈希图具有一些服务器信息,例如 ip_address 服务器名称,因此,我在map中都使用了值,并且将 ip_address用作键。然后,我在其他地图中存储了其他硬件规格,并且将ip_address作为密钥,在第三张地图中也是如此。

因此,基于密钥组合所有POJO 我将获得完整的服务器信息以及相应的ip_address。

不执行嵌套操作,我不知道怎么做

4 个答案:

答案 0 :(得分:0)

使用putAll()

Map<String, Server> all = new HashMap<>();
all.putAll(map1);
all.putAll(map2);
all.putAll(map3);

如果您想要单线:

Map<String, Server> all = Stream.of(map1, map2, map3)
    .reduce(new HashMap<>(), (a, b) -> {a.putAll(b); return a;});

冲突导致替换。

答案 1 :(得分:0)

这是一种执行此操作的方法。我已经展示了仅使用两个Map集合的示例代码,并且第三个可以类似的方式应用。

我正在使用Map的{​​{1}}方法来“合并”两个地图的值。 computeIfPresentBiFunction的参数)需要考虑“合并”方面-任何验证(目前尚不为我所知)。另外,请参见下面computeIfPresent上的注释。

示例代码:

computeIfPresent


输出:

import java.util.*;
import java.util.function.*; 

public class CombiningMaps {

    private static Map<String, ServerInfo> map1 = new HashMap<>();
    private static Map<String, ServerInfo> map2 = new HashMap<>();

    private static BiFunction<String, ServerInfo, ServerInfo> combineWithMap2 = 
        (k, v) -> {
                    if (map2.get(k) != null) {
                        ServerInfo v2 = map2.get(k);
                        // combine values of map1 and map2
                        v.setHw2(v2.getHw2());
                    }
                    return v;
                };

    public static void main(String [] args) {

        // Add some test data to map 1
        map1.put("serv1", new ServerInfo("0A", "a1", "",""));
        map1.put("serv2", new ServerInfo("0B", "b1", "",""));
        map1.put("serv3", new ServerInfo("0C", "c1", "",""));
        System.out.println(map1);

        // Add some data to map 2
        map2.put("serv1", new ServerInfo("0A", "", "a2",""));
        map2.put("serv2", new ServerInfo("0B", "", "b2",""));
        map2.put("serv3", new ServerInfo("0C", "", "c2",""));
        System.out.println(map2);

        // Update map1 with map 2's info
        map1.forEach((k,v) -> map1.computeIfPresent(k, combineWithMap2));
        System.out.println(map1);
    }
}

class ServerInfo {
    private String ipAddr;
    private String hw1; // hw stands for hardware related info
    private String hw2;
    private String hw3;
    public ServerInfo(String ipAddr, String hw1, String hw2, String hw3) {
        this.ipAddr = ipAddr;
        this.hw1 = hw1;
        this.hw2 = hw2;
        this.hw3 = hw3;
    }
    public String getIpAddr() {
        return ipAddr;
    }
    public String getHw1() {
        return hw1;
    }
    public void setHw1(String s) {
        hw1 = s;
    }
    public String getHw2() {
        return hw2;
    }
    public void setHw2(String s) {
        hw2 = s;
    }
    public String getHw3() {
        return hw3;
    }
    public void setHw3(String s) {
        hw3 = s;
    }
    public String toString() {
        return ipAddr + ":" + hw1 + "-" + hw2 + "-" +  hw3;
    }
}


computeIfPresent的行为方式(在某些情况下):

考虑一个具有键和值的{serv2=0B:b1--, serv3=0C:c1--, serv1=0A:a1--} {serv2=0B:-b2-, serv3=0C:-c2-, serv1=0A:-a2-} {serv2=0B:b1-b2-, serv3=0C:c1-c2-, serv1=0A:a1-a2-} 映射:Map<String, Integer>

(1)用新值更新映射(请注意,lambda是返回新计算值的{four=4, one=1, ten=10, two=2, three=3, five=5, eleven=11, twelve=null}):

BiFunction

(2)函数返回一个map.computeIfPresent("ten", (k, v) -> new Integer(100)); ,现有映射被删除:

null

(3)由于不存在现有映射,因此未添加映射:

map.computeIfPresent("eleven", (k, v) -> null);

(4)现有值为map.computeIfPresent("twenty", (k, v) -> new Integer(20)); ,所以没有变化:

null

答案 2 :(得分:0)

在获取三个地图中的所有值之后,我使用了finalMap来组合值。这是它的工作,因为密钥在所有地图中都是相同的,因此使用的密钥获取地图的密钥  map1是个好主意。

Set<Map.Entry<String, Server>> set1 = map.entrySet();  
                    for (Map.Entry<String, Server> me : set1) {
                        Server server=new Server();
                                     server.setIp_Address(me.getKey());
                                     server.setServerName(me.getValue().getServerName());
                                     server.setOsName(map1.get(me.getKey()).getOsName());
                                     server.setOsVersion(map1.get(me.getKey()).getOsVersion());
                                     server.setOsArchitecture(map1.get(me.getKey()).getOsArchitecture());
                                     server.setHardDiskCapacity(map1.get(me.getKey()).getHardDiskCapacity());
                                     server.setRamCapacity(map1.get(me.getKey()).getRamCapacity());
                                     server.setAvgNetWorkUtilizationSent(map2.get(me.getKey()).getAvgNetWorkUtilizationSent());
                                     server.setAvgNetworkUtilizationReceived(map2.get(me.getKey()).getAvgNetworkUtilizationReceived());
                                     server.setAvgCPUtilization(map2.get(me.getKey()).getAvgCPUtilization());
                                     server.setAvgRamUtilization(map2.get(me.getKey()).getAvgRamUtilization());
                                     finalMap.put(me.getKey(), server);
                   }
                    Set<Map.Entry<String, Server>> set2 = finalMap.entrySet();  
                    for (Map.Entry<String, Server> me : set2) {
            System.out.println(" ServerIP : "+ me.getValue().getIp_Address()+"\t"+" Server Name :"+me.getValue().getServerName()+"\t \t"+" Hardware Capacity :"+me.getValue().getHardDiskCapacity()+"\t"+" Average CPU Utlization: "+me.getValue().getAvgCPUtilization());
                    }

答案 3 :(得分:0)

您遇到的问题是合并两个POJO类。 例如

class Server {

    private String ipAddr;
    private String hw1;
    private String hw2;
    private String hw3;
    //Getter and Setters
}

Server s1 = new Server("0A", "a1", null, null);
Server s2 = new Server("0A", null, "b2", null);

所以合并的pojo应该是这样的。

Server merged = merge(s1, s2);// Server{ipAddr=0A, hw1=a1, hw2=b2, hw3=null}

合并功能看起来像这样...

public static Server merge(Server s1, Server s2) throws Exception {

    Server merged = new Server();

    for (Field field : Server.class.getDeclaredFields()) {
        field.setAccessible(true);
        Object getS1 = field.get(s1);
        Object getS2 = field.get(s2);

        if(getS1 == null && getS2 != null) {
            field.set(merged, getS2);
        } else if (getS1 != null && getS2 == null) {
            field.set(merged, getS1);
        } else {  //equal values
            field.set(merged, getS1);
        }
    }

    return merged;
}

这是合并三个地图的示例代码,虽然有点麻烦,但效果很好。

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

class MergeMaps {

public static void main(String[] args) throws Exception {

    Map<String, Server> map1 = new HashMap<>();
    Map<String, Server> map2 = new HashMap<>();
    Map<String, Server> map3 = new HashMap<>();

    // Add some test data to map 1
    map1.put("serv1", new Server("0A", "a1", null, null));
    map1.put("serv2", new Server("0B", "b1", null, null));
    System.out.println(map1);

    // Add some data to map 2
    map2.put("serv1", new Server("0A", null, "a2", null));
    map2.put("serv2", new Server("0B", null, "b2", null));
    map2.put("serv3", new Server("0C", null, "c2", null));
    System.out.println(map2);

    // Add some data to map 3
    map3.put("serv1", new Server("0A", null, null, "a3"));
    map3.put("serv2", new Server("0B", null, null, "b3"));
    map3.put("serv3", new Server("0C", null, null, "c3"));
    map3.put("serv4", new Server("0D", null, null, "d4"));
    System.out.println(map3);

    Map<String, Server> resultingMap = new HashMap<>();

    resultingMap.putAll(map1);

    for (Map.Entry<String, Server> entry : map2.entrySet()) {
        if (resultingMap.containsKey(entry.getKey())) {
            Server s = resultingMap.get(entry.getKey());
            Server t = entry.getValue();

            Server merged = merge(s, t);
            resultingMap.put(entry.getKey(), merged);
        } else {
            resultingMap.put(entry.getKey(), entry.getValue());
        }
    }

    for (Map.Entry<String, Server> entry : map3.entrySet()) {
        if (resultingMap.containsKey(entry.getKey())) {
            Server server1 = resultingMap.get(entry.getKey());
            Server server2 = entry.getValue();

            Server merged = merge(server1, server2);
            resultingMap.put(entry.getKey(), merged);
        } else {
            resultingMap.put(entry.getKey(), entry.getValue());
        }
    }
    System.out.println(resultingMap);
}

public static Server merge(Server s1, Server s2) throws Exception {

    Server merged = new Server();

    for (Field field : Server.class.getDeclaredFields()) {
        field.setAccessible(true);
        Object getS1 = field.get(s1);
        Object getS2 = field.get(s2);

        if (getS1 == null && getS2 != null) {
            field.set(merged, getS2);
        } else if (getS1 != null && getS2 == null) {
            field.set(merged, getS1);
        } else {
            field.set(merged, getS1);
        }
    }

    return merged;
}
}

class Server {

    private String ipAddr;
    private String hw1;
    private String hw2;
    private String hw3;

    public Server() {
    }

    public Server(String ipAddr, String hw1, String hw2, String hw3) {
        this.ipAddr = ipAddr;
        this.hw1 = hw1;
        this.hw2 = hw2;
        this.hw3 = hw3;
    }
    //Getter and setters
    @Override
    public String toString() {
        return "Server{" + "ipAddr=" + ipAddr + ", hw1=" + hw1 + ", hw2=" + hw2 +     ", hw3=" + hw3 + '}';
}
}

输出看起来像这样。

{serv2=Server{ipAddr=0B, hw1=b1, hw2=null, hw3=null}, serv1=Server{ipAddr=0A, hw1=a1, hw2=null, hw3=null}}
{serv2=Server{ipAddr=0B, hw1=null, hw2=b2, hw3=null}, serv3=Server{ipAddr=0C, hw1=null, hw2=c2, hw3=null}, serv1=Server{ipAddr=0A, hw1=null, hw2=a2, hw3=null}}
{serv2=Server{ipAddr=0B, hw1=null, hw2=null, hw3=b3}, serv3=Server{ipAddr=0C, hw1=null, hw2=null, hw3=c3}, serv4=Server{ipAddr=0D, hw1=null, hw2=null, hw3=d4}, serv1=Server{ipAddr=0A, hw1=null, hw2=null, hw3=a3}}
{serv2=Server{ipAddr=0B, hw1=b1, hw2=b2, hw3=b3}, serv3=Server{ipAddr=0C, hw1=null, hw2=c2, hw3=c3}, serv4=Server{ipAddr=0D, hw1=null, hw2=null, hw3=d4}, serv1=Server{ipAddr=0A, hw1=a1, hw2=a2, hw3=a3}}