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中常见的不可变对象及其特性:
-
String
类:String
类是最著名的不可变类之一。- 一旦创建,
String
对象的内容不能被改变。所有对String
对象的修改操作都会生成新的String
对象,而不是改变原有的对象。
-
Integer
、Long
、Double
、Float
、Character
、Short
、Byte
类:- 这些类是Java的包装类,用于表示基本数据类型(如
int
、long
、double
等)的对象。 - 这些包装类也是不可变的。一旦创建,它们的值不能被修改。
- 这些类是Java的包装类,用于表示基本数据类型(如
-
LocalDate
、LocalTime
、LocalDateTime
、Year
、Month
、Duration
、Period
(java.time
包中的类):- 这些类属于 Java 8 引入的
java.time
包,用于表示日期和时间。 - 这些类被设计为不可变,以支持并发编程并减少错误。
- 这些类属于 Java 8 引入的
-
BigInteger
和BigDecimal
类:BigInteger
和BigDecimal
用于处理任意精度的整数和浮点数。- 这些类也是不可变的,每次进行算术操作都会返回一个新的对象,而不是修改现有对象。
-
Path
类(java.nio.file
包中的类):Path
类表示文件路径,并且它也是不可变的。
-
Optional
类:Optional
用于表示一个可能为空的值。它的实例是不可变的,任何对Optional
的操作都会产生一个新的Optional
实例。
为什么使用不可变对象
-
线程安全: 不可变对象在多线程环境中天然是线程安全的,因为它们的状态在对象创建后不会改变,不需要同步。
-
简单性: 不可变对象的使用使得代码更易于理解和维护,因为它们的状态不变,避免了许多复杂的状态管理问题。
-
可缓存性: 不可变对象可以安全地被缓存或共享,因为它们不会改变自己的状态。
-
避免副作用: 不可变对象减少了副作用,因为方法不会改变对象的状态,而是返回一个新对象。
如何实现不可变对象
要创建一个不可变对象,通常需要遵循以下几个步骤:
- 声明类为
final
: 防止类被继承,从而保护其不可变性。 - 将字段声明为
final
: 确保字段在对象创建后不可修改。 - 提供没有修改对象状态的方法: 确保所有的字段都通过构造函数初始化,而不是提供任何修改字段的方法。
- 如果字段是可变对象的引用,确保不暴露该引用: 通过返回字段的副本或者使用不变的集合类来保护内部状态。
通过这些实践,可以确保对象的状态在创建后保持不变,进一步实现不可变性。