Java編程思想【溫故知新】
第一章:對象導論
1. 抽象過程(類與對象的關系)
類是一類對象的共同行為(成員函數)與狀態(成員變量),對象是具體類的實例化。(Eg.人類是一個類,共同的行為:吃,狀態:名字。)
【類創建者需要考慮這件事情,回頭看看這個概念四個字醍醐灌頂,每次創建這個類的時候,想一想這個類是需要什麽成員函數與成員變量來滿足單一職責的原則】
2. 每個對象都提供服務:程序設計本身的目標就是去創建能夠提供服務來解決問題的一系列對象。
3. 被隱藏的具體實現:類創建者與客戶端程序員使用者。
往往來說,每個程序員都是兩者身份的結合,類的創建者只要需要暴露需要暴露的行為,客戶端程序員使用者負責創建對象並使用。【封裝】
4. 復用具體類實現:在建立新的類時,應該優先考慮組合。Has a
【開放封閉原則】
5. 繼承:
以現有類為基礎,復制它,在子類中添加新的方法或者覆蓋舊的方法。is a(子類完全可以替換父類)與is like a(子類擁有父類不具備的功能)【多態】
6. 伴隨多態的可互換對象
向上轉型是安全的【裏氏替換原則】,向下轉型不是安全的。【依賴倒轉原則】
7. 單根繼承結構Object
任何一個類都是繼承至Object。
8. 容器(問題來了,容器是否會持有對其他對象的引用?答案:都是引用,會修改原始數據。抽查得出結果。)
Set:
HashSet:
public boolean add(E e) { return map.put(e, PRESENT)==null; } public V put(K key, V value) { if (table == EMPTY_TABLE) { inflateTable(threshold); } if (key == null) return putForNullKey(value); int hash = sun.misc.Hashing.singleWordWangJenkinsHash(key); int i = indexFor(hash, table.length); for (HashMapEntry<K,V> e = table[i]; e != null; e = e.next) { Object k; if (e.hash == hash && ((k = e.key) == key || key.equals(k))) { V oldValue = e.value; e.value = value; e.recordAccess(this); return oldValue; } } modCount++; addEntry(hash, key, value, i); return null; }
LinkedHashSet:extends HashSet。
TreeSet:
List:
ArrayList:
public boolean add(E e) { ensureCapacityInternal(size + 1); // Increments modCount!! elementData[size++] = e; return true; }
LinkedList:
public boolean add(E e) { linkLast(e); return true; } void linkLast(E e) { final Node<E> l = last; final Node<E> newNode = new Node<>(l, e, null); last = newNode; if (l == null) first = newNode; else l.next = newNode; size++; modCount++; }
Map:
HashMap:
public V put(K key, V value) { if (table == EMPTY_TABLE) { inflateTable(threshold); } if (key == null) return putForNullKey(value); int hash = sun.misc.Hashing.singleWordWangJenkinsHash(key); int i = indexFor(hash, table.length); for (HashMapEntry<K,V> e = table[i]; e != null; e = e.next) { Object k; if (e.hash == hash && ((k = e.key) == key || key.equals(k))) { V oldValue = e.value; e.value = value; e.recordAccess(this); return oldValue; } } modCount++; addEntry(hash, key, value, i); return null; } void addEntry(int hash, K key, V value, int bucketIndex) { if ((size >= threshold) && (null != table[bucketIndex])) { resize(2 * table.length); hash = (null != key) ? sun.misc.Hashing.singleWordWangJenkinsHash(key) : 0; bucketIndex = indexFor(hash, table.length); } createEntry(hash, key, value, bucketIndex); } void createEntry(int hash, K key, V value, int bucketIndex) { HashMapEntry<K,V> e = table[bucketIndex]; table[bucketIndex] = new HashMapEntry<>(hash, key, value, e); size++; } HashMapEntry(int h, K k, V v, HashMapEntry<K,V> n) { value = v; next = n; key = k; hash = h; }
另外:其實List就是將Map的key變成下標:0/1/2/3.../n,而Set就是將Map的value變成null。
9. 對象的創建與生命周期
雖然說java有垃圾回收機制,但是前提是必須了解java內存模型(pc、虛擬機棧、本地方法棧、堆、方法區各自的作用)
10. 異常處理:處理錯誤
11. 並發編程
1、區分並發與並行的區別,假設只有一個處理器,兩者個人認為是表現一致的。
2、並發與並行的區別:在於同一時刻。(Eg. 並發:你在吃飯的過程中,電話來了,你只能放下手中的飯筷去聽電話。並行:你在吃飯的過程中,電話來了,你可以邊吃飯邊聽電話。)
3、在java編程中,程序是不關心並行或者是並發,只有邏輯線程的概念。
Java編程思想【溫故知新】