关于数据知识点联想
文章目录
一.按是否可变分类
1.immutable
immutable类是指这个类的实例一旦创建完成后,就不能改变其成员变量值,也就是不能改变对象的状态。首先,类需要声明为final,保证其不可以被继承,所有成员变量定义为private final,不提供改变成员变量的Mutators方法 ,通过构造器初始化成员变量,如果构造器传入了引用数据类型需要进行防御式拷贝。
常用的immutable数据
如String,一旦被创建,始终指向同一个值/引用。如果编译器无法确定final变量不会改变,就提示错误,这也是静态类型检查的一部分。
对于基本数据类型和其封装的类都是immutable的
优点是immutable数据类型,在rep中定义为private final,可防止表示泄露。
缺点是immutable数据类型,在使用时如果改变其引用(对象数据类型),会多次创建新的对象,降低效率。
例如,我们对内容为“a”string进行修改时,会创建新的String内容为“ab”的对象,并指向。
equals()
equals(),不可变类型应该重写equals()和hashCode()
①引用等价性
即==,判断值是否相同或引用的对象是否地址相同
②对象等价性
判断两者内容是否相同
2.mutable
mutable类是指其类创建完成后,其内部含有Mutators方法,或者存在不是可以改变的rep。
常用的mutable数据
所有的list,map,数组都是mutable的。就算我们将其定义为private final,确定其指向对象不可变,并且无法外部访问。但其内容仍然可变。
优点是是频繁的修改对象时都是在原对象的基础上修改,并不需要重新创建,这样可以有效的利用内存,不会造成内存空间的浪费。所以在不需要暴露给client的ADT中,在不涉及到表示泄露的情况下,我们可以更多地使用mutable。
例如,我们对Stringbuider的修改
缺点如果在应用中修改过于频繁,或类中存在mutators方法,则易导致内存泄露。
部分mutable数据可以转为immutable
如list可以通过Java给我们提供的方法Collections,unmodifiableList将其转化为不可变的数据。英文中unmodifiable 即只读的意思,不可以修改。
List<String> s=Collections.unmodifiableList(new ArrayList<>());
但可惜的是数组Java没有提供直接转换的方法。
equals()
①行为等价性
改变一个对象而不改变另外一个时,仍然无法区分对象(例如有相同引用),调用对象的任何方法都展示出一致的结果
②观察等价性
在不改变对象状态的情况下(不使用mutator),无法区分对象,即两个mutable对象是否看起来一致
例如:
Date类的equals() 的spec:"两个Date 类型的getTime 方法返回结果相同,才是相同的Date. “
List类的equals() 的spec:"如果两个List以相同的顺序包含相同的元素,才能定义为相等的List
可变类型不应该重写equals()和hashCode(),采用Object默认实现的即可。也就是只有指向同样内存空间的objects,才是相等的,实现行为等价性即可
线程安全
mutable数据可以根据其是否线程安全分为两部分
线程安全是由于同意进程内多个线程并行执行,且共享计算资源如内存。所以在多线程读写全局变量间出现竞争导致的。
线程安全是指多个线程在执行同一段代码的时候采用加锁机制,使每次的执行结果和单线程执行的结果都是一样的,不存在执行结果的二义性。线程不安全就是不提供加锁机制保护,有可能出现多个线程先后更改数据造成所得到的数据是脏数据
①unthreadsafe data
线程不安全的数据如上文中的StringBuilder,LIst,Map等数据类型。
但安全与不安全之间同样可以转换
StringBuffer是StringBuilder的线程安全类。而List,Map同样可以通过神奇的Collections包装成线程安全的。
List<String> s=Collections.synchronizedList(new ArrayList<>());
②threadsafe data
我们常见的线程安全数据分为两种
一种是private final的immutable数据,其因为是只读数据,不存在读写间的竞争关系,所以线程安全。
另一种线程安全的数据因每一行代码都是原子执行的,如private final的包装后的LIst,Map。
注:存在即合理,线程不安全的数据虽然安全性较差,但在性能上却更能体现出多线程的优越性,所以在局部变量中,可以多使用线程不安全但高效的类。
二.按照值与对象分类
1.引用(对象)数据类型
引用类型(reference type)指向一个对象,不是原始值,指向对象的变量是引用变量,也就是指向内存中的地址空间。
在java里面除去基本数据类型的其它类型都是引用数据类型,自己定义的class类都是引用类型,可以像基本类型一样使用。
引用类型常见的有:String,StringBuffer,ArrayList,HashSet,HashMap等。
如果要对比两个对象是否相同,则需要使用equals()方法,但有一点需要注意:equals()方法的默认行为是比较引用。如果是你自己写的类,你应该为它重写equals()来比较对象的内容。大多数Java类库都实现了比较对象内容的equals()方法。
2.基本数据类型
基本数据类型都是immutable的