[JAVA] Thinking In Java细节复习(三)

来源:互联网 发布:mysql负载均衡 编辑:程序博客网 时间:2024/05/13 16:17

1.内部类的继承:由于内部类构建器必须同封装类对象的一个句柄联系到一起,所以从一个内部类继承的时候。句柄必须获得初始化,而且在衍生类中不再有一个默认的对象可以连接

// Inheriting an inner classclass WithInner {       class Inner {}}public class InheritInner extends WithInner.Inner {       //! InheritInner() {}     // Won't compile       InheritInner(WithInner wi) {              wi.super();       }       public static void main(String[] args) {              WithInner wi = new WithInner();              InheritInner ii = new InheritInner(wi);       }} 
InheritInner只对内部类进行了扩展,没有扩展外部类。但在需要创建一个构建器的时候, 默认对象已经没有意义,我们不能只是传递封装对象的一个句柄。此外,必须在构建器中采用下述语法: enclosingClassHandle.super(); 它提供了必要的句柄,以便程序正确编译。


2.构建器(constructor)调用顺序:

(1) 调用基础类构建器。这个步骤会不断重复下去,首先得到构建的是分级结构的根部,然后是下一个衍生 类,等等。直到抵达最深一层的衍生类。

(2) 按声明顺序调用成员初始化模块。 

(3) 调用衍生构建器的主体。  


3.集合:

(1)一般只应该用ListIterator对一 个ArrayList 进行向前和向后遍历,不要用它删除和插入元素,与 LinkedList相比,它的效率要低许多 LinkedList 提供优化的顺序访问性能,同时可以高效率地在列表中部进行插入和删除操作。但在进行随机访 问时,速度却相当慢,此时应换用 ArrayList,正是由于这个原因,假如想在一个列表中部进行大量插入和删除操 作,那么LinkedList 无疑是最恰当的选择。
(2)ArrayMap 由一个 ArrayList后推得到的 Map。对反复的顺序提供了精确的控制。面向非常小的 Map设计,特 别是那些需要经常创建和删除的。对于非常小的Map,创建和反复所付出的代价要比 HashMap低得多。但在 Map变大以后,性能也会相应地大幅度降低
(3)进行add()以及contains()操作时,HashSet显然要比 ArraySet 出色得多,而且性能明显与元素的多寡关系不大。一般编写程序的时候,几乎永远用不着使用 ArraySet。
(4)在ArrayList 中进行随机访问(即get())以及循环反复是最划得来的;但对于LinkedList 却是 一个不小的开销。但另一方面,在列表中部进行插入和删除操作对于 LinkedList 来说却比ArrayList 划算得多。我们最好的做法也许是先选择一个ArrayList 作为自己的默认起点。以后若发现由于大量的插入和删除造成了性能的降低,再考虑换成LinkedList不迟。

4.HashMap和HashTable的区别
(1)HashMap几乎可以等价于Hashtable,除了HashMap是非synchronized的,并可以接受null(HashMap可以接受为null的键值(key)和值(value),而Hashtable则不行)。这意味着Hashtable是线程安全的,多个线程可以共享一个Hashtable;而如果没有正确的同步的话,多个线程是不能共享HashMap的。Java 5提供了ConcurrentHashMap,它是HashTable的替代,比HashTable的扩展性更好。
(2)另一个区别是HashMap的迭代器(Iterator)是fail-fast迭代器,而Hashtable的enumerator迭代器不是fail-fast的。所以当有其它线程改变了HashMap的结构(增加或者移除元素),将会抛出ConcurrentModificationException,但迭代器本身的remove()方法移除元素则不会抛出ConcurrentModificationException异常。但这并不是一个一定发生的行为,要看JVM。这条同样也是Enumeration和Iterator的区别。
(3)由于Hashtable是线程安全的也是synchronized,所以在单线程环境下它比HashMap要慢。如果你不需要同步,只需要单一线程,那么使用HashMap性能要好过Hashtable。
(4)HashMap不能保证随着时间的推移Map中的元素次序是不变的。
(5)哈希值的使用不同,Hashtable直接使用对象的hashCode,代码是这样的:
int hash = key.hashCode();int index = (hash & 0x7FFFFFFF) % tab.length;
而HashMap重新计算hash值,而且用与代替求模
int hash = hash(k);int i = indexFor(hash, table.length);static int hash(Object x) {  int h = x.hashCode();  h += ~(h << 9);  h ^= (h >>> 14);  h += (h << 4);  h ^= (h >>> 10);  return h;}static int indexFor(int h, int length) {  return h & (length-1);
(6)Hashtable中hash数组默认大小是11,增加的方式是 old*2+1。HashMap中hash数组的默认大小是16,而且一定是2的指数。



0 0
原创粉丝点击