数组的拷贝
2023-02-18 16:39:24 时间
数组的拷贝
背景
一个数组中有多个map,要重复操作在map中插入个随机数,把map存到新的数组中,发现会有相同的map
@Test
public void test4() {
Random r = new Random();
List<Map<String, Object>> l = new ArrayList<>();
List<Map<String, Object>> l1 = new ArrayList<>();
Map<String, Object> m = new HashMap<>();
m.put("a", "1");
Map<String, Object> m1 = new HashMap<>();
m1.put("a", "2");
l1.add(m);
l1.add(m1);
for (int i = 0; i < 3; i++) {
for (Map<String, Object> b : l1) {
int t = r.nextInt(1000);
b.put("c", t);
System.out.println(t);
}
l.addAll(l1);
}
System.out.println(l);
}
输出结果:
851
543
204
668
108
347
[{a=1, c=108}, {a=2, c=347},
{a=1, c=108}, {a=2, c=347},
{a=1, c=108}, {a=2, c=347}]
尽管每次插入的随机数不同,但是发现结果是重复的,因为循环操作了同一个数组l1,而数组l中保存的是l1的地址(l.addAll(l1);)导致最后的结果是3组相同的数据。
解决方案:新建一个数组l2去接收数组l1的数据,每次操作新数组,实现数据隔离
方案一:List.addAll()(浅拷贝)
List<Map<String, Object>> l2 = new ArrayList<>();
l2.addAll(l1);
方案二:使用List的构造方法(浅拷贝)
List<Map<String, Object>> l2 = new ArrayList<>(l1);
@Test
public void test5() {
Random r = new Random();
List<Map<String, Object>> l = new ArrayList<>();
List<Map<String, Object>> l1 = new ArrayList<>();
Map<String, Object> m = new HashMap<>();
m.put("a", "1");
Map<String, Object> m1 = new HashMap<>();
m1.put("a", "2");
l1.add(m);
l1.add(m1);
for (int i = 0; i < 3; i++) {
// 方案一
// List<Map<String, Object>> l2 = new ArrayList<>();
// l2.addAll(l1);
// 方案二
List<Map<String, Object>> l2 = new ArrayList<>(l1);
for (Map<String, Object> b : l2) {
int t = r.nextInt(1000);
b.put("c", t);
System.out.println(t);
}
l.addAll(l2);
}
System.out.println(l);
}
输出结果还是重复的数据
751
812
509
957
512
874
[{a=1, c=512}, {a=2, c=874},
{a=1, c=512}, {a=2, c=874},
{a=1, c=512}, {a=2, c=874}]
打印JSONObject.toJSONString()打印结果会发现还是相同的地址引用
System.out.println(JSONObject.toJSONString(l));
结果:
[{"a":"1","c":995},{"a":"2","c":946},
{"$ref":"$[0]"},{"$ref":"$[1]"},
{"$ref":"$[0]"},{"$ref":"$[1]"}]
方案三:数据类型转换(深拷贝)
@Test
public void test6() {
Random r = new Random();
List<Map<String, Object>> l = new ArrayList<>();
List<Map<String, Object>> l1 = new ArrayList<>();
Map<String, Object> m = new HashMap<>();
m.put("a", "1");
Map<String, Object> m1 = new HashMap<>();
m1.put("a", "2");
l1.add(m);
l1.add(m1);
for (int i = 0; i < 3; i++) {
// 方案三,转成String,在转回List
String str = JSONObject.toJSONString(l1);
List<Map<String, Object>> l2 = JSONObject.parseObject(str, List.class);
for (Map<String, Object> b : l2) {
int t = r.nextInt(1000);
b.put("c", t);
System.out.println(t);
}
l.addAll(l2);
}
System.out.println(l);
}
测试发现数据没有重复,实现数据隔离
941
685
901
129
449
516
[{"a":"1","c":941}, {"a":"2","c":685},
{"a":"1","c":901}, {"a":"2","c":129},
{"a":"1","c":449}, {"a":"2","c":516}]
当然还有其他序列化方式的深度拷贝都能实现数据隔离,之后在补充
相关文章
- 运营商三要素实名认证接口(姓名、身份证号、手机号)
- 2022-12-16:给你一个长度为n的数组,并询问q次 每次询问区间[l,r]之间是否存在小于等于k个数的和大于等于x 每条查询返回true或者false。
- Metaverse、Web3 和 NFT 的必然性
- STM32使用硬件I2C读取SHTC3温湿度传感器并显示在0.96寸OLED屏上
- STM32单片机读取AHT10温湿度传感器数据
- 大数据Kudu(四):Kudu集群搭建
- 指点云 宿迁 12900K高防云服务器 性能测评,4核8G 10兆 150G防御 仅需160元/月
- STM32软件I2C读取AM2320温湿度传感器数据
- 自从用了灰度发布,睡觉真香!
- Spring Cloud 最新版发布,Spring Security + OAuth2 终于安排上了!
- Spring 6.0 正式发布,新王登基!!
- Spring Boot 3.0 正式发布,王炸!!
- 你还只会用 AtomicXXX ?!恭喜你,可以下岗了!
- 牛逼啊,ChatGPT 能接入微信了!
- Nacos 2.2 正式发布,这次更新太炸了!
- 经验分享:如何开发一个成功的 NFT 项目,社区建设技巧
- 记住,永远都不要在 Flutter 中使用全局变量
- Web3 系列开发教程:创建第一个智能合约(1)什么是智能合约
- 使用 Web Animations API 实现一个精确计时的时钟
- 15 款企业级零代码开发平台推荐,总有一款是你心仪的