java map value值是引用的变量?

本文解决了在使用Map存储对象时遇到的值对象变化问题。通过每次存储前创建新的对象实例,避免了对象引用导致的数据错误。

今天碰到个奇怪的问题,花了很久终于找到原因。

原来代码类似如下:


 getFinancalReport tf=new getFinancalReport();
    	  for(int i=1;i<sheetResult.getRows();i++)
    	  {
    		  String teamLeader=sheetResult.getCell(12,i).getContents().trim();
    		  double amt=Double.parseDouble(sheetResult.getCell(4,i).getContents().trim());
    		  if(!map.containsKey(teamLeader))
    		  {
    			  //每次存进去都要新建,否则会出问题
    			
    			  tf.amt=amt;
    			  map.put(teamLeader,tf);
    		  }else
    		  {
    			 
    			  tf.amt=amt+map.get(teamLeader).amt;
    			  map.put(teamLeader,tf);
    		  }

结果每次运行map的value值都会变,如下图:


第一次运行key为杨的value值是10,但当插入key为叶的值后,杨的value值也会跟着变。

后来改成如下代码:

 for(int i=1;i<sheetResult.getRows();i++)
    	  {
    		  String teamLeader=sheetResult.getCell(12,i).getContents().trim();
    		  double amt=Double.parseDouble(sheetResult.getCell(4,i).getContents().trim());
    		 
    		  if(!map.containsKey(teamLeader))
    		  {
    			  //每次存入map都要新建对象
    			  getFinancalReport tf=new getFinancalReport();
    			  tf.amt=amt;
    			  map.put(teamLeader,tf);
    		  }else
    		  {
    			  getFinancalReport tf=new getFinancalReport();
    			  tf.amt=amt+map.get(teamLeader).amt;
    			  map.put(teamLeader,tf);
    		  }

正常了


猜测是存入map时,value值直接引用了tf对象,所以跟着该对象值也会变。后续再研究




### 三级标题:JavaMap传递和引用传递机制 在 Java 中,`Map` 是一种常用的键对集合类,用于储和操作数据。理解 `Map` 的传递与引用传递机制对于编写高效、安全的代码非常重要。 #### 传递 Java 中的所有参数传递都是**传递**。这意味着当一个变量作为参数传递给方法时,实际上是该变量的一个拷贝被传递了过去。对于基本数据类型(如 `int`、`long`),这意味着传递的是实际的数;而对于对象类型(包括 `Map` 实例),传递的是对象引用的副本[^5]。 例如,考虑以下代码片段: ```java public class MapExample { public static void main(String[] args) { Map<String, Integer> originalMap = new HashMap<>(); originalMap.put("one", 1); modifyMap(originalMap); System.out.println(originalMap); // 输出 {one=2} } public static void modifyMap(Map<String, Integer> map) { map.put("one", 2); } } ``` 在这个例子中,尽管 `modifyMap` 方法接收的是 `originalMap` 的副本引用,但由于这个副本引用指向的是同一个 `HashMap` 实例,因此对 `map` 所做的修改也会影响到 `originalMap` [^4]。 #### 引用传递 虽然 Java 只支持传递,但有时我们会看到类似“引用传递”的行为。这是因为当我们把一个对象(比如 `Map`)传递给一个方法时,传递的是该对象的引用的一个拷贝。这意味着如果方法内部更改了对象的状态(如添加或删除条目),这些更改将反映在原始对象上。然而,如果我们让方法内的参数指向一个新的对象,则外部的变量不会受到影响,因为这仅改变了参数本身的引用,而不是它所指向的对象[^5]。 下面是一个展示这一点的例子: ```java public class ReferenceVsValue { public static void main(String[] args) { Map<String, String> myMap = new HashMap<>(); myMap.put("key", "value"); changeReference(myMap); System.out.println(myMap); // 输出仍然是 {key=value} } public static void changeReference(Map<String, String> map) { map = new HashMap<>(); // 这里只是改变了局部变量map引用 map.put("newKey", "newValue"); } } ``` 在这个案例中,即使我们在 `changeReference` 方法内创建了一个新的 `HashMap` 并将其赋给了 `map` 参数,`main` 方法中的 `myMap` 变量依然指向原来的 `HashMap` 实例,并没有受到任何影响。 #### 工作原理 Java 中的对象(如 `Map`)本质上是通过引用来管理的,但这并不意味着 Java 支持引用传递。Java 中的引用传递行为实际上是由传递实现的,即传递的是对象引用的副本。如果方法内部修改了对象的状态,这些修改会反映到原始对象上,因为它们都指向同一个对象。但如果方法内部将参数重新指向一个新的对象,外部的变量不会受到影响,因为这只是改变了参数的引用,而不是对象本身。 此外,`Map` 的实现类(如 `HashMap`)依赖于对象的 `hashCode()` 和 `equals()` 方法来判断键是否相等。如果自定义类作为 `Map` 的键,必须正确重写 `hashCode()` 和 `equals()` 方法,以确保相同的键能够正确地映射到对应的。`HashMap` 中的比较逻辑是先计算 `hashCode()`,如果相同再调用 `equals()` 来进一步确认是否相等。如果只重写了 `hashCode()` 而不重写 `equals()`,则默认的 `equals()` 方法会基于内地址进行比较,这可能导致错误的结果[^1]。 ### 相关问题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值