关于java中map先获取value,再对value修改 ,会不会对原map中数据修改的问题;

6 篇文章 0 订阅

List

package com.itheima.d5_Map;


import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class test3 {
    public static void main(String[] args) {
        Map<Integer, List<Integer>> mp = new HashMap<>() ;
        List<Integer> list = new ArrayList<>() ;
        list.add(1) ;
        list.add(2) ;
        mp.put(1,list) ;
        List<Integer> list1 = new ArrayList<>() ;
        list1.add(3) ;
        list1.add(4) ;
        mp.put(2,list1) ;

        List<Integer> a = mp.getOrDefault(1, new ArrayList<>()) ;
        a.add(3) ;

        for(Map.Entry<Integer,List<Integer>> entry : mp.entrySet()){
            System.out.println(entry.getKey()+" "+entry.getValue());
        }
    }
}

运行结果 : 

可以看到用a获取map[1]之后 , 往a中添加数据 , 最后map中的数据会得到相应的修改

自定义的类

package com.itheima.d5_Map;

import com.sun.jdi.IntegerValue;

import java.util.HashMap;
import java.util.Map;

public class test2 {
    public static void main(String[] args) {
        Map<Integer,A> mp = new HashMap<>() ;
        mp.put(1,new A("a1","b1")) ;
        mp.put(2,new A("a2","b2")) ;

        A a = mp.getOrDefault(1, new A()) ;
        a.setName("yss");

        for(Map.Entry<Integer,A> entry : mp.entrySet()){
            System.out.println(entry.getKey()+" "+entry.getValue().getName());
        }
    }
}

其中类A为 : 

运行结果 : 

可以看到原map中的数据也被修改了 ;

结论  : 

  • 当map中的value是一个不可变的对象的时候 ,如果修改也是产生一个新对象 , 而原对象的值是不会变的 , 所以是不会修改原map中的值的 ;
  • 如果是一个可变的对象 ,因为map中存入的是该对象的引用 ,虽然先获取出来 ,但是修改之后 , 还是会修改原map中的数据 ;

java中的不可变类

在Java中,不可变对象(Immutable Objects)是指一旦创建后其状态无法被修改的对象。不可变对象的一个关键特点是它们的状态(即对象的字段值)在创建之后不能被更改。这种特性使得不可变对象在多线程环境中更加安全,能够避免线程间的同步问题。

以下是一些Java中常见的不可变对象及其特性:

  1. String:

    • String 类是最著名的不可变类之一。
    • 一旦创建,String 对象的内容不能被改变。所有对 String 对象的修改操作都会生成新的 String 对象,而不是改变原有的对象。
  2. IntegerLongDoubleFloatCharacterShortByte:

    • 这些类是Java的包装类,用于表示基本数据类型(如 intlongdouble 等)的对象。
    • 这些包装类也是不可变的。一旦创建,它们的值不能被修改。
  3. LocalDateLocalTimeLocalDateTimeYearMonthDurationPeriodjava.time 包中的类):

    • 这些类属于 Java 8 引入的 java.time 包,用于表示日期和时间。
    • 这些类被设计为不可变,以支持并发编程并减少错误。
  4. BigIntegerBigDecimal:

    • BigInteger 和 BigDecimal 用于处理任意精度的整数和浮点数。
    • 这些类也是不可变的,每次进行算术操作都会返回一个新的对象,而不是修改现有对象。
  5. Path 类(java.nio.file 包中的类):

    • Path 类表示文件路径,并且它也是不可变的。
  6. Optional:

    • Optional 用于表示一个可能为空的值。它的实例是不可变的,任何对 Optional 的操作都会产生一个新的 Optional 实例。

为什么使用不可变对象

  1. 线程安全: 不可变对象在多线程环境中天然是线程安全的,因为它们的状态在对象创建后不会改变,不需要同步。

  2. 简单性: 不可变对象的使用使得代码更易于理解和维护,因为它们的状态不变,避免了许多复杂的状态管理问题。

  3. 可缓存性: 不可变对象可以安全地被缓存或共享,因为它们不会改变自己的状态。

  4. 避免副作用: 不可变对象减少了副作用,因为方法不会改变对象的状态,而是返回一个新对象。

如何实现不可变对象

要创建一个不可变对象,通常需要遵循以下几个步骤:

  1. 声明类为 final: 防止类被继承,从而保护其不可变性。
  2. 将字段声明为 final: 确保字段在对象创建后不可修改。
  3. 提供没有修改对象状态的方法: 确保所有的字段都通过构造函数初始化,而不是提供任何修改字段的方法。
  4. 如果字段是可变对象的引用,确保不暴露该引用: 通过返回字段的副本或者使用不变的集合类来保护内部状态。

通过这些实践,可以确保对象的状态在创建后保持不变,进一步实现不可变性。

  • 16
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值