站点介绍
hashCode() 的作用是获取哈希码,也称为散列码;它实际上是返回一个int整数。这种哈希码的作用是确认该对象在哈希表中的索引地点。hashCode() 定义在JDK的Object.java中,这就说明着Java中的所有类都包含有hashCode()函数。
散列表存储的是键值对(key-value),它的特点是:能根据“键”急速的检索出对应的“值”。这之中就使用到了散列码!(合适急速寻找所需要的对象)
我们以“HashSet 怎么样检查重复”为举例来说明怎么要有 hashCode:
当你把对象加入 HashSet 时,HashSet 会先计算对象的 hashcode 值来判断对象加入的地点,同一时间也会与很多的已经加入的对象的 hashcode 值作对比,如果没有相符的hashcode,HashSet会假设对象没有重复出现。但是如果发现有相同 hashcode 值的对象,这时会调用equals()方法来检查 hashcode 相等的对象是否真的相同。如果两者相同,HashSet 就不会让其加入操作成功。如果不一样的话,就会从头开始散列到很多的地点。(摘自我的Java启蒙书《Head first java》第二版)。这样我们就大大减少了 equals 的次数,相应就大大提高了执行速度。
hashCode()与equals()的有关规定
如果两个对象相等,则hashcode一定也是相同的
两个对象相等,对两个对象分别调用equals方法都返回true
两个对象有相同的hashcode值,它们也不一定是相等的
因此,equals 方法被覆盖过,则 hashCode 方法也一定被覆盖
hashCode() 的默认行为是对堆上的对象发生特别值。如果没有重写 hashCode(),则该 class的两个对象无论怎么样都不可能相等(即便这两个对象指向相同的资料)
对象的相等与指向他们的引用相等,两者有什么不一样?
对象的相等 比的是内存中存放的内容是否相等而 引用相等 对比的是他们指向的内存地址是否相等。
1. 抽象类合适提供成员方法的实现细节,而接口中就只能存在public abstract 方法;
2. 抽象类中的成员变量合适是各种类别的,而接口中的成员变量就只能是public static final类别的;
3. 接口中不合适含有静态代码块以及静态方法,而抽象类合适有静态代码块和静态方法;
4. 一个类就只能继承一个抽象类,而一个类却合适实现多个接口。
46.Java 8的接口新增了哪些特性?
增加了default方法和static方法,这2种方法合适有方法体。
重写是子类对父类的允许访问的方法的实现过程进行从头开始编写, 返回值和形参都不合适变化。即外壳不变,核心重写!
重写的好处在于子类合适根据需要,定义特殊于自己的行为。 也只是说子类能够根据需要实现父类的方法。
重写方法不合适抛出新的检查不正常或者比被重写方法申明更加宽泛的不正常。
重载(overloading) 是在一个类里面,方法名字相同,而参数不一样。返回类别合适相同也合适不一样。
每一个重载的方法(或者构造函数)都一定有一个不可复制的参数类别列表
1. ArrayList和LinkedList的差别主要来自于Array和LinkedList资料结构的不一样。
ArrayList是基于数组实现的,LinkedList是基于双链表实现的。另外LinkedList类不仅是List接口的实现类,合适根据索引来随机访问集合中的元素,除此之外,LinkedList还实现了Deque接口,Deque接口是Queue接口的子接口,它代表一个双向队列,因此LinkedList合适作为双向队列 ,栈(合适参见Deque提供的接口方法)和List集合使用,功能厉害。
2. 因为Array是基于索引(index)的资料结构,它使用索引在数组中搜索和读取资料是很快的,合适直接返回数组中index地点的元素,因此在随机访问集合元素上有较好的性能。Array获取资料的时间繁琐度是O(1),但是要插入、删除资料却是开销蛮大的,因为这需要移动数组中插入地点之后的的全部元素。
3. 相对于ArrayList,LinkedList的随机访问集合元素时性能较差,因为需要在双向列表中寻找要index的地点,再返回;但在插入,删除操作是更快的。因为LinkedList不像ArrayList一样,不需要变化数组的大小,也不需要在数组装满的时候要将全部的资料从头开始装入一个新的数组,这是ArrayList最坏的一种状态,时间繁琐度是O(n),而LinkedList中插入或删除的时间繁琐度仅为O(1)。ArrayList在插入资料时还需要更新索引(除了插入数组的尾部)。
4. LinkedList需要再多的内存,因为ArrayList的每一个索引的地点是实际的资料,而LinkedList中的每一个节点中存储的是实际的资料和前后节点的地点。
静态代理中代理类在编译期就已经确认,而动态代理则是JVM运行时动态生成,静态代理的效率相对动态代理来说相对高一些,但是静态代理代码冗余大,一单需要改写接口,代理类和委托类都需要改写
JDK动态代理就只能对实现了接口的类生成代理,而不合适针对类。
CGLIB是针对类实现代理,往往一般是对指定的类生成一个子类,覆盖之中的方法。因为是继承,所以该类或方法最好不要声明成final。