通过引用传递HashMap

时间:2015-06-09 13:51:43

标签: 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()&amp;的所有数据。 addLow()遗失了。这是为什么?

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

我可以做些什么来确保addMid()addLow()更新主人HashMap()

编辑:包含的代码。它编译并运行,但还有其他问题,我尽可能多地去除了证明发生了什么,除了SQL的东西,不能编译,抱歉。在start时运行的方法是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;
    }
} 

2 个答案:

答案 0 :(得分:2)

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

createObject()

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

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

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

一个小例子:

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

但为什么呢?不应该是&#39; c?d?没有!因为Java中的String是不可变的,但Map不是。如果你考虑到这一点,你应该能够解决你的问题。

答案 1 :(得分:1)

您需要检查此密钥是否已有地图:

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

如果没有这个,第二次尝试将值添加到同一个键将覆盖现有的地图而不是附加到它。