equals、hashCode、toString、深/浅拷贝

279 阅读3分钟
方法javakotlin
equals判断两个对象是否是同一个对象。当自定义equals方法时,一定要自定义hashCode方法,以保证用什么来进行equals就用什么来进行hashCode同java
hashCode获取对象的hash摘要。equals方法返回true(即两个对象相等),那么hashCode一定相等;euqals方法返回false(即两个对象不相等),那么hashCode值可以相等。但是从性能优化的角度来看,对于两个不同的对象返回不同的hashCode会提高哈希表的性能(即会降低哈希冲突)同java
toString对于String类型对象来说,java为我们重写了toString,默认打印字符串值;对于其他普通类来说,默认打印的是对象地址data类重写了基类Any中的toString方法,默认打印该对象成员变量的键值对;对普通类的toString的处理和java一样,默认打印对象地址
浅拷贝在需要拷贝的类上实现Cloneable接口并重写其clone()方法。如果属性是基本类型(int,double,long,boolean等),拷贝的就是基本类型的值;如果属性是引用类型,拷贝的就是内存地址(即复制引用但不复制引用的对象)kotlin为data类提供copy方法,对于拷贝对象是基本数据类型和String类型来说,会创建新对象;对于拷贝对象中的引用类型,只拷贝其地址。也就是说,如果一个对象中含有引用类型变量,那么拷贝该对象后,所产生的新对象中的引用类型变量,将和原来对象中的引用类型变量共用一个,即地址相同。(修改新对象中引用类型变量的值,将会影响原来对象中引用类型变量的值。所以如果data类中包含了 基本数据类型和String 之外的引用类型 的字段, 那么必须自己实现深拷贝操作。)
深拷贝创建一个新的对象,是完全独立于原对象的,所以无论怎么修改属性,另一个对象中的属性也不会随着改变。那么如何实现深拷贝呢?先调用对象的 clone() 方法,对对象的引用类型的属性值,继续调用clone()方法进行二次拷贝。很简单,看示例:AAA clone = (AAA) super.clone();clone.bbb = ((BBB) bbb.clone())。当然也可以通过序列化和反序列化重新生成新对象进行深拷贝。将拷贝对象中的引用类型也一并递归拷贝其中的内容,而不是仅仅复制其地址,生成的是一个新对象。 (修改新对象中引用类型变量的值,不会影响原来对象中引用类型变量的值。)那么如何实现深拷贝呢?很简单,看示例:val a = AAA(1,BBB(2));val b = a.copy(bbb = BBB(100)),直接在copy方法中进行引用类型的重新赋值。当然也可以通过序列化和反序列化重新生成新对象进行深拷贝。
componentN实际上具体到实现中并不是特指componentN()这一个方法,N只是表示1、2、3等序列,实际使用中会提到N,比如component1()、component2()等等,那具体有多少个component呢?这取决于类的主构造方法中有多少个属性。注意只能是主构造方法中的属性,其他地方定义的都不行。示例:val p = Person("zhangsan", 20); p.component1()打印出来就是"zhangsan"。