首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >通过引用传递HashMap

通过引用传递HashMap
EN

Stack Overflow用户
提问于 2015-06-09 13:51:43
回答 2查看 4.8K关注 0票数 0

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

代码语言:javascript
复制
HashMap<String, HashMap<String, ArrayList<String>>>

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

代码语言:javascript
复制
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()

代码语言:javascript
复制
out = new HashMap();
data.put(val, out);
return out;

当我检查循环/数据填充结束时,来自addMid() & addLow()的所有数据都丢失了。为什么会这样呢?

我认为Java在处理复杂对象(如HashMap() )时是引用的。

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

编辑:包含代码。它编译和运行,但还有其他问题,我已经尽可能地剥离,以演示发生了什么,除了SQL的东西,不会编译,对不起。启动时运行的方法是sqlToArray();

代码语言:javascript
复制
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;
    }
} 
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-06-09 14:23:30

您需要检查是否已经有此键的地图:

代码语言:javascript
复制
Map<...> result = data.get(val);
if(null == result) {
    result = new HashMap();
    data.put(val, result);
}
return out;

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

票数 1
EN

Stack Overflow用户

发布于 2015-06-09 14:17:33

要小心,不要意外地重写现有的映射值。如果使用java 8,则可以使用:

代码语言:javascript
复制
map.computeIfAbsent("entry", s -> new ArrayList<>());

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

代码语言:javascript
复制
List<String> list = map.get("entry");

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

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

一个小小的例子:

代码语言:javascript
复制
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);

产出如下:

代码语言:javascript
复制
b
b
c

所以,如果你更新b,地图就不会更新。现在地图中的地图也是一样的:

代码语言:javascript
复制
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));

产出如下:

代码语言:javascript
复制
c
d
d

但是为什么呢?不是应该是“c-c”吗?不是的!因为Java中的字符串是不可变的,但是Map不是。如果你考虑到这一点,你应该能够解决你的问题。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30734053

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档