这属于我在开发中碰过的坑 ,容器中存放者对象,当clear()的时候,出现的奇葩问题。好了,直接看代码:

package com.DataType.yinyong;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map; public class TestMethod {
//我总结了一下,因为实际开发中涉及到代码层级较深,所以有时候会不容易看出问题
public static void main(String[] args) {
TestMethod testMethod =new TestMethod();
List<Map<String, List<Object>>> resultMaps = new ArrayList<Map<String, List<Object>>>();
resultMaps.add(testMethod.getList());
testMethod.testXunHuan(resultMaps); } public void testXunHuan(List<Map<String, List<Object>>> resultMaps) {
for (Map<String, List<Object>> resultMap : resultMaps) {
int resultNum = 0;
List<Object> result = resultMap.get("r1");
resultMap.remove("r1");
if (result == null)
continue;
resultNum = result.size();
if (resultNum <= 0) {
continue;
}
for (int i = 0; i < result.size(); i++) {
Object o = result.get(i);
}
result.clear();
System.out.println("虽然 我修改的result是指向r1,但是我的map内的另外一个值 :"+resultMap.get("r12"));
}
} public Map<String, List<Object>> getList() {
Map<String, List<Object>> resultMap = new HashMap<String, List<Object>>();
//下面我提供一个List<Object>,并且让resultMap中不同的key引用相同的值
Map<String, List<Object>> srcMap = new HashMap<String, List<Object>>();
List<Object> srcList = new ArrayList<Object>();
for(int i = 0 ; i < 10;i++){
srcList.add("count");
}
srcMap.put("key1", srcList);
srcMap.put("key2", srcList);
//下面我声明一个新的list用来
List<Object> result = srcMap.get("key1");
resultMap.put("r1", result);
List<Object> result2 = srcMap.get("key2");
resultMap.put("r12", result2);
System.out.println("resul实际上是一个"+(result ==result2) );
return resultMap;
} }

输出结果:

总结 :

  1,java中是弱化了引用还是传值的概念,也不需要考虑指针。

    2, 但有些时候,特别是容器内还是需要注意一下,有可能Map中两个key指向的value是同一个对象,这时候,当你选择拿到一个值 clear(),就会出现错误

  3, 于是你可以采用两种方式解决这一问题

     ① :如果不去clear(),的确不会对其他数据产生影响,但是会造成内存消耗大,实际开发不可取(实际开发中不可能只有这两个键值对)

     ② :可以选择copy一下数组,但是同样的原因导致不可取(注意collections.copy()方法是如何使用的

public Map<String, List<Object>> getList() {
Map<String, List<Object>> resultMap = new HashMap<String, List<Object>>();
//下面我提供一个List<Object>,并且让resultMap中不同的key引用相同的值
Map<String, List<Object>> srcMap = new HashMap<String, List<Object>>();
List<Object> srcList = new ArrayList<Object>();
for(int i = 0 ; i < 10;i++){
srcList.add("count");
}
List<Object> srcList1 = new ArrayList<Object>();
Collections.addAll(srcList1, new Object[srcList.size()]);
Collections.copy(srcList1, srcList);//collection.copy(dest,src)方法需要dest的size大于等于src、属于深copy
srcMap.put("key1", srcList);
srcMap.put("key2", srcList1);
//下面我声明一个新的list用来
List<Object> result = srcMap.get("key1");
resultMap.put("r1", result);
List<Object> result2 = srcMap.get("key2");
resultMap.put("r12", result2);
System.out.println("resul实际上是一个List么"+(result ==result2) );
return resultMap;
}

  4;最终我决定,每次clear之前,先去判断是否存在有其他key用到

public void testXunHuan(List<Map<String, List<Object>>> resultMaps) {
for (Map<String, List<Object>> resultMap : resultMaps) {
int resultNum = 0;
List<Object> result = resultMap.get("r1");
resultMap.remove("r1");
if (result == null)
continue;
resultNum = result.size();
if (resultNum <= 0) {
continue;
}
for (int i = 0; i < result.size(); i++) {
Object o = result.get(i);
}
boolean isExistSame =false;
Iterator< List<Object>> ite= resultMap.values().iterator();
while(ite.hasNext()){
if(ite.next().equals(result)){
isExistSame = true;
break;
}
}
//只有不存在相同值,才可以删除
if(!isExistSame){
result.clear();
}
System.out.println("虽然 我修改的result是指向r1,但是我的map内的另外一个值 :"+resultMap.get("r12"));
}
}

参考:

由java中深度复制一伸出Collections.copy的使用

Java中的深拷贝(深复制)和浅拷贝(浅复制)

渐析java的浅拷贝和深拷贝

    

Java开发中碰到的Map的坑的更多相关文章

  1. 编写高质量代码:改善Java程序的151个建议(第一章:JAVA开发中通用的方法和准则)

    编写高质量代码:改善Java程序的151个建议(第一章:JAVA开发中通用的方法和准则) 目录 建议1: 不要在常量和变量中出现易混淆的字母 建议2: 莫让常量蜕变成变量 建议3: 三元操作符的类型务 ...

  2. Java开发中常用jar包整理及使用

    本文整理了我自己在Java开发中常用的jar包以及常用的API记录. <!-- https://mvnrepository.com/artifact/org.apache.commons/com ...

  3. paip.java 开发中web server的选择jboss resin tomcat比较..

    paip.java 开发中web server的选择jboss resin tomcat比较.. 作者Attilax  艾龙, EMAIL:1466519819@qq.com 来源:attilax的专 ...

  4. Java开发中常见的危险信号(中)

    本文来源于我在InfoQ中文站原创的文章,原文地址是:http://www.infoq.com/cn/news/2013/12/common-red-flags-in-java-1 Dustin Ma ...

  5. Java开发中文件读取方式总结

    JAVA开发中,免不了要读文件操作,读取文件,首先就需要获取文件的路径. 路径分为绝对路径和相对路径. 在文件系统中,绝对路径都是以盘符开始的,例如C:\abc\1.txt. 什么是相对路径呢?相对路 ...

  6. java开发中遇到的问题及解决方法(持续更新)

    摘自 http://blog.csdn.net/pony12/article/details/38456261 java开发中遇到的问题及解决方法(持续更新) 工作中,以C/C++开发为主,难免与其他 ...

  7. Java开发中常见的危险信号(上)

    本文来源于我在InfoQ中文站原创的文章,原文地址是:http://www.infoq.com/cn/news/2013/12/common-red-flags-in-java-1 Dustin Ma ...

  8. 完整java开发中JDBC连接数据库代码和步骤[申明:来源于网络]

    完整java开发中JDBC连接数据库代码和步骤[申明:来源于网络] 地址:http://blog.csdn.net/qq_35101189/article/details/53729720?ref=m ...

  9. Java 开发中的对象拷贝

    前言 在 Java 开发中,很多时候需要将两个属性基本相同的对象进行属性复制,比如 DO 转 VO等等. 本文主要介绍自己实现的简易拷贝工具类与 Spring 提供的属性拷贝的对比. Spring 提 ...

随机推荐

  1. 默认路由、RIPv2、OSPF、EIGRP配置(全网全通)

    1:默认路由 遇到问题:给r2配置向右的单项默认路由,通过PC1去ping主机PC2,一直显示Request timed out, 解决方法:r2配置如下: r2(config)#ip route 0 ...

  2. LiteIDE灰调配色方案

    说明 本文写于2017-04-03,使用LiteIDE X31(基于Qt 4.8.5),操作系统为Windows. 使用 LiteIDE下载后解压即可使用.配色方案的所有配置文件都位于liteide/ ...

  3. superagent和request结果转换区别

    superagent和request结果转换区别 使用superagent和request抓取页面内容时,两个抓取内容都可以被cheerio进行处理.但处理时有个细微差别. 1. 使用superage ...

  4. 第39篇 免费博客github Pages绑定域名

    原文地址:http://blog.laofu.online/2017/06/02/how-bind-domain/ 网站已经有了,需要对网站来绑定一个自己的个性域名,本人是买了一个阿里云的域名,也就是 ...

  5. charles抓包,打断点,连接手机抓包

    写给我自己: 如果是使用charles抓包.一定要tm的保证手机和电脑连的是一个网. charles抓本地包的操作 1.打开charles, 2.打开浏览器访问某网页,就可抓到对应的包 charles ...

  6. Spring学习(15)--- 基于Java类的配置Bean 之 @Bean & @Scope 注解

    默认@Bean是单例的,但可以使用@Scope注解来覆盖此如下: @Configuration public class MyConfiguration { @Bean @Scope("pr ...

  7. zookeeper 新手安装指南

    Zookeeper集群的角色:  Leader 和  follower  (Observer) zk集群最好配成奇数个节点 只要集群中有半数以上节点存活,集群就能提供服务 本事例采用版本:zookee ...

  8. javamail 邮件格式再优化(由详情——>改为统计)

    前言:之前扩展的ant-jmeter支持邮件附件形式上传以及邮件内容的html文件格式. 如图: 由于邮件的内容格式是详情信息,也就是说直观的显示的是case,但由于case的增加,邮件内容越来越大! ...

  9. [1] Ninject

    为什么使用这种依赖注入的框架呢?我借鉴两张图做一下说明 传统的接口方式,即 IValueCalculator I=new LinqValueCalculator,虽然用接口做的隔离,但是在调用的时候实 ...

  10. 可选参数、命名参数、.NET的特殊类型、特性

    1.可选参数和命名参数    1.1可选参数        语法:            [修饰符] 返回类型 方法名(必选参数n,可选参数n)        注意:            1.必选参 ...