[英]Java - Best way to update HashMap value - Pass by value/reference related
[英]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.