马上就要面试了,再把这些集合类拿出来复习:
首先先上集合类的继承关系图
详情见:http://blog.csdn.net/HHcoco/article/details/53117525
看集合类的继承关系图,以及类之间关系,对Java接口的作用,模板方法有了进一步的理解。
首先谈谈接口,从程序角度来看,接口就是函数的声明,类才是函数的实现。所以这样来看接口更像是一种规范、一种协议,这样的好处就是通过接口我就可以简单明了的了解实现这个接口的类的方法、功能,而不用关心具体的类的具体方法以及具体实现。
运用模板方法的设计思想,使用抽象类与具体类 。
将公共的逻辑以具体方法、具体构造函数的形式存放在抽象类中,提高代码的复用,避免类似代码在子类中重复出现,然后再声明一些抽象方法去迫使子类去实现剩余的逻辑,不同的子类可以用不同的方式去实现这些抽象方法,从而对剩余逻辑有不同的实现。
HashMap
首先明确,HashMap的实现是数组+链表。即一个长度为length的数组中,每个元素的存储的是一个链表的头结点。
存储的过程一般为key的哈希值取模得到下标值。对于下标值相同的value,使用前插法插入到链表中,即数组中存储的是最后插入的元素。
当然HashMap里面也包含一些优化方面的实现,这里也说一下。比如:Entry[]的长度一定后,随着map里面数据的越来越长,这样同一个index的链就会很长,会不会影响性能?HashMap里面设置一个因子,随着map的size越来越大,Entry[]会以一定的规则加长长度。
每次扩到2倍的原长。
ArrayList
ArrayList是list接口的可变数组的实现。
每当向数组中添加元素时,都要去检查添加后元素的个数是否会超出当前数组的长度,如果超出,数组将会进行扩容,以满足添加数据的需求。数组扩容通过一个公开的方法ensureCapacity(int minCapacity)来实现。在实际添加大量元素前,我也可以使用ensureCapacity来手动增加ArrayList实例的容量,以减少递增式再分配的数量。
数组进行扩容时,会将老数组中的元素重新拷贝一份到新的数组中,每次数组容量的增长大约是其原容量的1.5倍。这种操作的代价是很高的,因此在实际使用时,我们应该尽量避免数组容量的扩张。当我们可预知要保存的元素的多少时,要在构造ArrayList实例时,就指定其容量,以避免数组扩容的发生。或者根据实际需求,通过调用ensureCapacity方法来手动增加ArrayList实例的容量。