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编程中,程序是不关心并行或者是并发,只有逻辑线程的概念。