我想要制作地图的备份副本(包含其他地图)。 我有这样的事情:
Map<TYPE1, Map<TYPE2, TYPE3>>
TYPE1,TYPE2和TYPE3是由我创建的3个不同类的对象(例如,该类的组件是:String,Integer,Double,....)
我试过
Map<TYPE1, Map<TYPE2, TYPE3>> Map2= new HashMap<TYPE1, Map<TYPE2, TYPE3>>(Map1)
[....make some changings in Map1...]
Map1 = new HashMap<TYPE1, Map<TYPE2, TYPE3>>(Map2)
Map1是我想制作副本的原始地图。 我也试过PutAll方法,但它不起作用(Map的内容与原来的不一样)。
你知道其他方法吗?谢谢。
答案 0 :(得分:0)
因为集合中的键和值是您自定义的类。 地图中的那些内容并未真正复制,而是共享“TYPE”的相同实例。 你需要做这样的事情来复制所有内容的价值。 这只是一个非常简单的例子,因此没有任何封装。
public class Foo1 {
public Integer a = 0;
public Foo1() {
}
public Foo1(Integer a) {
this.a = a;
}
public Foo1 clone() {
return new Foo1();
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + getOuterType().hashCode();
result = prime * result + ((a == null) ? 0 : a.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Foo1 other = (Foo1) obj;
if (!getOuterType().equals(other.getOuterType()))
return false;
if (a == null) {
if (other.a != null)
return false;
} else if (!a.equals(other.a))
return false;
return true;
}
}
public class Foo2 {
public Integer a = 0;
public Foo2() {
}
public Foo2(Integer a) {
this.a = a;
}
public Foo2 clone() {
return new Foo2();
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + getOuterType().hashCode();
result = prime * result + ((a == null) ? 0 : a.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Foo1 other = (Foo1) obj;
if (!getOuterType().equals(other.getOuterType()))
return false;
if (a == null) {
if (other.a != null)
return false;
} else if (!a.equals(other.a))
return false;
return true;
}
}
public class Foo3 {
public Integer a = 0;
public Foo3() {
}
public Foo3(Integer a) {
this.a = a;
}
public Foo3 clone() {
return new Foo3();
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + getOuterType().hashCode();
result = prime * result + ((a == null) ? 0 : a.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Foo1 other = (Foo1) obj;
if (!getOuterType().equals(other.getOuterType()))
return false;
if (a == null) {
if (other.a != null)
return false;
} else if (!a.equals(other.a))
return false;
return true;
}
}
自己复制你的价值。
Map<Foo1, Map<Foo2, Foo3>> map1 = new HashMap<Foo1, Map<Foo2, Foo3>>();
Map<Foo1, Map<Foo2, Foo3>> map2 = new HashMap<Foo1, Map<Foo2, Foo3>>();
Map<Foo2, Foo3> tmp = new HashMap<Foo2, Foo3>();
tmp.put(foo.new Foo2(), foo.new Foo3());
map1.put(foo.new Foo1(), tmp);
for (Foo1 key : map1.keySet()) {
Map<Foo2, Foo3> tmp2 = new HashMap<>();
for (Foo2 key2 : map1.get(key).keySet()) {
tmp2.put(key2.clone(), map1.get(key).get(key2).clone());
}
map2.put(key, tmp2);
}
for (Foo1 key : map1.keySet()) {
for (Foo2 key2 : map1.get(key).keySet()) {
map1.get(key).get(key2).a = 10;//change map1's value
}
}
for (Foo1 key : map2.keySet()) {
for (Foo2 key2 : map2.get(key).keySet()) {
System.out.println(map2.get(key).get(key2).a);// the value in map2 still 0
}
}
答案 1 :(得分:0)
关于深拷贝的非常有趣的文章: How do you make a deep copy of an object in Java?
使用序列化/反序列化,你不需要进入你的课程, 而你不会忘记一些变数。 它给出了:
Map<Integer, Map<String,String>> mimss =new HashMap<Integer, Map<String,String>>();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(mimss);
oos.flush();
oos.close();
bos.close();
byte[] byteData = bos.toByteArray();
ByteArrayInputStream bais = new ByteArrayInputStream(byteData);
Map<Integer, Map<String,String>> mimss_copy=(Map<Integer, Map<String,String>>) new ObjectInputStream(bais).readObject();
如果要将其保存在文本中,也可以在中间转换为B64:
String serial= DatatypeConverter.printBase64Binary(byteData);
byte[] byteData_reverse=DatatypeConverter.parseBase64Binary(serial);
要求:TYPE1,TYPE2,TYPE3必须是可序列化的
是可序列化的,你的班级必须是那样的
public class myclass implements Serializable
你应该(不是强制性的)在
中声明private static final long serialVersionUID = 6569838532917408380L;
如果里面的任何内容也可序列化,那就没关系(标准类型是,集合,......)