繁体   English   中英

通过引用传递HashMap

[英]pass a HashMap by reference

我有一个多维HashMap()实例,我正在使用它们来存储数据库中的分层数据。

HashMap<String, HashMap<String, ArrayList<String>>>

我用3种主要方法添加到它们中,我们将它们称为addTop()addMid()addLow() 这些方法都接受与其数据组和字符串匹配的参数,每个方法都返回HashMap()的下一个维度;

public static HashMap<String, ArrayList<String>> addTop(HashMap<String, HashMap<String, ArrayList<String>>> data, String val) { ... };
public static ArrayList<String> addMid(HashMap<String, ArrayList<String>> data, String val) { ... };
public static String addLow(ArrayList<String> data, String val) { ... };

我通常在几次检查之间依次调用这些方法,并在方法内部执行其他检查。 本质上,所有这些方法所做的就是将val添加到data然后返回一个空的HashMap()

out = new HashMap();
data.put(val, out);
return out;

当我在循环/数据填充末尾检查时,来自addMid()addLow()所有数据都丢失了。 为什么是这样?

我认为Java在处理复杂对象(例如HashMap()时可以通过引用来工作。

如何确保addMid()addLow()更新主HashMap()

编辑:包含的代码。 它可以编译并运行,但是还有其他问题,抱歉,我竭尽所能地演示了发生的事情,除了不能编译的SQL内容。 在启动时运行的方法是sqlToArray();

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;

public class Av2 {
    protected class AvailLookup {
        private Integer key;
        private String value;
        public AvailLookup(Integer inKey, String inValue) {
            key = inKey;
            value = inValue;
        }
        public void updateName(String name) {
            value = name;
        }
        public Integer getKey() {
            return key;
        }
        public String getValue() {
            return value;
        }
        public String toString() {
            return value;
        }
    }
    private static HashMap<AvailLookup, HashMap<AvailLookup, ArrayList<AvailLookup>>> data = new HashMap<AvailLookup, HashMap<AvailLookup, ArrayList<AvailLookup>>>();
    private static Sql sql = new Sql("PlantAvail");
    public static HashMap<AvailLookup,  ArrayList<AvailLookup>> getChannel(HashMap<AvailLookup, HashMap<AvailLookup, ArrayList<AvailLookup>>> inArray, Integer channel) {
        HashMap<AvailLookup, ArrayList<AvailLookup>> out = null;
        if (inArray != null ) {
            for (AvailLookup lookup : inArray.keySet()) {
                if (lookup.getKey() == channel) {
                    out = inArray.get(lookup);
                    System.out.println("Channel: " + channel + " found");
                    break;
                }
            }
            if (out == null) {
                System.out.println("Channel: " + channel + " not found");
            }
        }
        return out;
    }
    public static HashMap<AvailLookup,  ArrayList<AvailLookup>> getChannel(HashMap<AvailLookup, HashMap<AvailLookup, ArrayList<AvailLookup>>> inArray, String channel) {
        HashMap<AvailLookup, ArrayList<AvailLookup>> out = null;
        if (inArray != null ) {
            for (AvailLookup lookup : inArray.keySet()) {
                if (lookup.getValue() != null) {
                    if (lookup.getValue().equalsIgnoreCase(channel)) {
                        out = inArray.get(lookup);
                        System.out.println("Channel: " + channel + " found");
                        break;
                    }
                }
            }
            if (out == null) {
                System.out.println("Channel: " + channel + " not found");
            }
        }
        return out;
    }
    public static HashMap<AvailLookup, ArrayList<AvailLookup>> addChannel(HashMap<AvailLookup, HashMap<AvailLookup, ArrayList<AvailLookup>>> inArray, Integer id, String name) {
        HashMap<AvailLookup, ArrayList<AvailLookup>> out = null;
        if (inArray != null ) {
            if (getChannel(inArray, id) == null) {
                out = new HashMap<AvailLookup, ArrayList<AvailLookup>>();
                inArray.put(new AvailLookup(id, name), new HashMap<AvailLookup, ArrayList<AvailLookup>>());
                System.out.println("Channel: added " + id);
            } else {
                System.out.println("Channel: " + id + " already exists");
            }
        } else {
            System.out.println("Channel: " + id + " already exists");
        }
        return out;
    }
    public static void removeChannel(HashMap<AvailLookup, HashMap<AvailLookup, ArrayList<AvailLookup>>> inArray, Integer channel) {
        boolean pass = false;
        HashMap<AvailLookup,  ArrayList<AvailLookup>> channelLookup = getChannel(inArray, channel);
        for (AvailLookup lookup : channelLookup.keySet()) {
            if (lookup.getKey() == channel) {
                inArray.remove(channel);
                System.out.println("Channel: " + channel + " removed");
                pass = true;
                break;
            }
        }
        if (!pass) {
            System.out.println("Channel: " + channel + " cannot be removed");
        }
    }
    public static ArrayList<AvailLookup> getDevice(HashMap<AvailLookup, ArrayList<AvailLookup>> channel, Integer device) {
        ArrayList<AvailLookup> out = null;
        for(AvailLookup lookup : channel.keySet()) {
            if (lookup.getKey() == device) {
                out = channel.get(device);
                System.out.println("Device: " + device + " found");
                break;
            }
        }
        if (out == null) {
            System.out.println("Device: " + device + " not found");
        }
        return out;
    }
    public static ArrayList<AvailLookup> getDevice(HashMap<AvailLookup, ArrayList<AvailLookup>> channel, String device) {
        ArrayList<AvailLookup> out = null;
        for(AvailLookup lookup : channel.keySet()) {
            if (lookup.getValue() == device) {
                out = channel.get(device);
                System.out.println("Device: " + device + " found");
                break;
            }
        }
        if (out == null) {
            System.out.println("Device: " + device + " not found");
        }
        return out;
    }
    public static ArrayList<AvailLookup> addDevice(HashMap<AvailLookup, ArrayList<AvailLookup>> channel, Integer id, String value) {
        ArrayList<AvailLookup> out = null;
        if (getDevice(channel, id) == null) {
            out = new ArrayList<AvailLookup>();
            channel.put(new AvailLookup(id, value), new ArrayList<AvailLookup>());
            System.out.println("Device: added " + id);
        } else {
            System.out.println("Device: " + id + " already exists");
        }
        return out;
    }
    public static void removeDevice(HashMap<AvailLookup, ArrayList<AvailLookup>> channel, Integer device) {
        boolean pass = false;
        ArrayList<AvailLookup> deviceLookup = getDevice(channel,device);
        for (AvailLookup lookup : deviceLookup) {
            if (lookup.getKey() == device) {
                channel.remove(device);
                System.out.println("Device: " + device + " removed");
                pass = true;
                break;
            }
        }
        if (!pass) {
            System.out.println("Device: " + device + " cannot be removed");
        }
    }
    public static AvailLookup getHost(ArrayList<AvailLookup> hosts, Integer host) {
        AvailLookup out = null;
        for (AvailLookup hostLookup : hosts) {
            if (hostLookup.getKey() == host) {
                out = hostLookup;
                System.out.println("Host: " + host + " found");
            }
        }
        if (hosts.contains(host)) {
        } else { 
            System.out.println("Host: " + host + " not found");
        }
        return out;
    }
    public static AvailLookup getHost(ArrayList<AvailLookup> hosts, String host) {
        AvailLookup out = null;
        for (AvailLookup hostLookup : hosts) {
            if (hostLookup.getValue() == host) {
                out = hostLookup;
                System.out.println("Host: " + host + " found");
            }
        }
        if (hosts.contains(host)) {
        } else { 
            System.out.println("Host: " + host + " not found");
        }
        return out;
    }
    public static AvailLookup addHost(ArrayList<AvailLookup> hosts, Integer id, String value) {
        AvailLookup out = null;
        for (AvailLookup hostLookup : hosts) {
            if (hostLookup.getKey() == id) {
                out = hosts.set(id, new AvailLookup(id, value));
                System.out.println("Host: " + id + " found");
                break;
            }
        }
        if (out == null) {
            System.out.println("Host: " + id + " not found");
        }
        return out;
    }
    public static void removeHost(ArrayList<AvailLookup> hosts, Integer host) {
        boolean pass = false;
        for (AvailLookup hostLookup : hosts) {
            if (hostLookup.getKey() == host) {
                hosts.remove(hostLookup);
                System.out.println("Host: " + host + " removed");
                pass = true;
            }
        }
        if (!pass) {
            System.out.println("Host: " + host + " cannot be removed");
        }
    }
    public static ArrayList<AvailLookup> otherHosts(ArrayList<AvailLookup> hosts, Integer key, String value) {
        ArrayList<AvailLookup> out = null;
        for (AvailLookup host : hosts) {
            if (host.getKey() != key) {
                if (out == null) {
                    out = new ArrayList<AvailLookup>();
                }
                out.add(new AvailLookup(key, value));
            }
        }
        if (out != null) {
            if (out.size() > 1) {
                System.out.println("Host: generated other hosts");
            }
        }
        return out;
    }
    public static AvailLookup nextHost(ArrayList<AvailLookup> otherHosts) {
        AvailLookup out = null; 
        if (otherHosts != null) {
            out = otherHosts.get(0);
            System.out.println("Host: getting next host");
        } else {
            System.out.println("Host: no other host");
        }
        return out;
    }
    public static void sqlToArray() {
        HashMap<AvailLookup, HashMap<AvailLookup, ArrayList<AvailLookup>>> tempData = new HashMap<AvailLookup, HashMap<AvailLookup, ArrayList<AvailLookup>>>();
        Integer iHost = null;
        Integer iDevice = null;
        Integer iChannel = null;
        String sHost = null;
        String sDevice = null;
        String sChannel = null;
        HashMap<AvailLookup, ArrayList<AvailLookup>> channel = null;
        ArrayList<AvailLookup> device = null;
        Sql obj = new Sql("plantavail");
        obj.query("select j_channel.id as channelid, j_channel.name as channelname, j_device.id as deviceid, j_device.name as devicename, j_io.id as hostid, j_io.host as hostname, alias"
                + " from j_io"
                + " left join j_channel on j_io.id = j_channel.iofk"
                + " left join j_device on j_channel.iofk = j_device.id");
        try {
            while(obj.getResult().next()) { 
                sChannel = obj.getResult().getString("channelname");
                sDevice = obj.getResult().getString("devicename");
                sHost = obj.getResult().getString("hostname");
                iChannel = obj.getResult().getInt("channelid");
                iDevice = obj.getResult().getInt("deviceid");
                iHost = obj.getResult().getInt("hostid");
                channel = addChannel(tempData, iChannel, sChannel);
                if (channel != null) {
                    device = addDevice(channel, iDevice, sDevice);
                    if (device != null) {
                        addHost(device, iHost, sHost);
                    }
                }
            }
        } catch (SQLException e1) {
            e1.printStackTrace();
        }
        data = tempData;
    }
} 

小心覆盖意外的现有地图值。 如果您使用Java 8,则可以使用:

map.computeIfAbsent("entry", s -> new ArrayList<>());

在Java 8之前,您需要检查该值是否为null:

List<String> list = map.get("entry");

if(list == null){
   list = map.put("entry", new ArrayList<String>());
}

另外,您还需要确保正确更新地图:

一个小例子:

Map<String, String> map = new HashMap<>();

String a = "a";
String b = "b";

map.put(a, b);

System.out.println(map.get(a));

b = "c";

System.out.println(map.get(a));
System.out.println(b);

输出为:

b
b
c

因此,您可以查看是否更新了地图,但地图并未更新。 现在,地图中的地图也是如此:

final String a = "a";
final String b = "b";

Map<String, Map<String, String>> topMap = new HashMap<>();
Map<String, String> middleMap = topMap.getOrDefault(a, new HashMap<>());

middleMap.put(b, "c");

topMap.put("a", middleMap);

System.out.println(topMap.get(a).get(b));

middleMap.replace(b, "d");

System.out.println(topMap.get(a).get(b));

topMap.put("a", middleMap);

System.out.println(topMap.get(a).get(b));

输出为:

c
d
d

但为什么? 应该不是“ cc d”吗? 没有! 因为Java中的String是不可变的,但Map不是。 如果您考虑这一点,则应该能够解决您的问题。

您需要检查此键是否已存在:

Map<...> result = data.get(val);
if(null == result) {
    result = new HashMap();
    data.put(val, result);
}
return out;

否则,第二次尝试向相同键添加值的尝试将覆盖现有映射,而不是附加到现有映射。

暂无
暂无

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

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