这里对ADT中的几个重要概念进行一些总结,ADT的思想可谓贯穿这门课的始终,其中包含的表示泄漏、抽象函数AF、表示不变量RI等特性,以及mutable,immutable的概念也是在实验中多次使用。
抽象函数AF:表示空间R和抽象空间A之间映射关系的函数,即如何去解释R中的每一个值为A中的每一个值。满足以下特征:
满射、非单射、 未必双射 (因为R中的部分值并非合法的, 在A中无映射值)
表示不变性RI:某个具体的“表示”是否是“合法的” §,也可将RI看作:所有表示值的一个子集,包含了所有合法的表示值 ,或者是一个条件,描述了什么是“合法”的表示值。
可变对象(mutable)和不可变对象(immutable)
不可变对象(Immutable Objects)即对象一旦被创建,它的状态(如对象的属性)就不能改变,任何对它的改变都应该产生一个新的对象。
可变对象(Mutable Objects):创建实例后可以改变其成员变量值,开发中创建的大部分类都属于可变类。
编写一个immutable类的方法:
1、使用private和final修饰符来修饰该类的属性。
2、不提供更改属性的方法。
3、不共享对可变对象的引用。不要直接使用对外部可变对象的引用,因为引用可变对象的成员变量和外部可变对象的引用指向同一块内存地址,用户可以修改可变对象的值,这样就会破坏不可变性。
4、确保类不能被继承:将类声明为final, 或者使用静态工厂,并将构造器声明为private类型。类如果被继承,会破坏其不可变性,因为子类可能覆盖父类的方法并且可以改变成员变量值。
immutable类的优点:
1、不可变类是线程安全的,可以不被synchronized修饰就在并发环境中共享
2、不可变对象简化了程序开发,因为它无需使用额外的锁机制就可以在线程之间共享
3、不可变对象提高了程序的性能,因为它减少了synchronized的使用
4、不可变对象时可以被重复利用的,你可以将它们缓存起来,就像字符串字面量和整型数值一样,可以使用静态工厂方法来提供类似于valueOf这样的方法,它可以从缓存中返回一个已经存在的不可变对象,而不是重新创建一个
缺点:immutable类不能被重用,会制造出大量的垃圾。
在Snapshot diagram中,可变对象是单线圈,不可变对象是双线圈:
可变类型
不可变类型
表示泄露和防御式拷贝
通过防御式拷贝,给客户端返回一个全新的对象(副本),客户端即使对数据做了更改,也不会影响到自己,但因为大部分时候该拷贝不会被客户端修改,所以可能造成大量的内存浪费,如果使用不可变类型,就能节省频繁复制的代价。例如Lab2中返回顶点的集合时:
@Override public Set<L> vertices() {
return new HashSet<L>(vertices);
}