java - 通过引用传递 HashMap

标签 java

我有一个多个多维 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;
    }
} 

最佳答案

小心不要意外覆盖现有的 map 值。如果您使用 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 :

一个小例子:

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

所以你看看如果你更新b, map 不会更新。现在, map 中的 map 也是如此:

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

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

关于java - 通过引用传递 HashMap,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30734053/

相关文章:

java - 列出文件夹和子文件夹的文件路径

java - 尝试使用 usb4java 高级库

java - 动态流布局

java - 使用 count() 时命名参数中的 JPA 错误

java - JPA中的多级继承

java - 在 JSP 中获取多对一 hibernate

java - 两个不同 soap 版本的系统属性 "javax.xml.soap.MessageFactory"

java - 删除对象变量的所有实例

java - 紧凑的反模式、基于 DetachedCriteria 的 hibernate DAO 实用程序有多危险?

java - 如何使用spring boot制作一个通用库