### ArrayList
* ArrayList類支持能夠按需增長的動態數組,增長策略oldCapacity + \(oldCapacity >> 1\)即原來的長度+原長度的一半
```
int newCapacity = oldCapacity + (oldCapacity >> 1);
```
* 默認容量大小是10
```
private static final int DEFAULT_CAPACITY = 10;
```
### 主要API
* **add\(E e\)**
add主要的執行邏輯如下:
1)確保數組已使用長度(size)加1之后足夠存下下一個數據
2)修改次數modCount 標識自增1,如果當前數組已使用長度(size)加1后的大于當前的數組長度,則調用grow方法,增長數組,grow方法會將當前數組的長度變為原來容量的1.5倍。
```
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
```
3)確保新增的數據有地方存儲之后,則將新元素添加到位于size的位置上。
4)返回添加成功布爾值;
```
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
```
* **add\(int index, E element\)**

這個方法其實和上面的add類似,該方法可以按照元素的位置,指定位置插入元素,具體的執行邏輯如下:
1)確保數插入的位置小于等于當前數組長度,并且不小于0,否則拋出異常
2)確保數組已使用長度(size)加1之后足夠存下下一個數據
3)修改次數modCount標識自增1,如果當前數組已使用長度(size)加1后的大于當前的數組長度,則調用grow方法,增長數組
4)grow方法會將當前數組的長度變為原來容量的1.5倍。
5)確保有足夠的容量之后,使用System.arraycopy 將需要插入的位置(index)后面的元素統統往后移動一位。
6)將新的數據內容存放到數組的指定位置(index)上
* grow\(\)擴容
```
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}
```
* **get\(int index\)**
```
public E get(int index) {
rangeCheck(index);
return elementData(index);
}
```
* **remove\(int index\)**
根據索引remove
1)判斷索引有沒有越界
2)自增修改次數
3)將指定位置(index)上的元素保存到oldValue
4)將指定位置(index)后的元素都往前移動一位
5)將最后面的一個元素置空,好讓垃圾回收器回收
6)將原來的值oldValue返回
```
public E remove(int index) {
rangeCheck(index);
modCount++;
E oldValue = elementData(index);
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // clear to let GC do its work
return oldValue;
}
```
_**注意:調用remove方法不會縮減數組的長度,只是將最后一個數組元素置空而已**_
* trimToSize\(\)縮小集合容量
* toArray\(\)將集合轉換為數組
* Arrays初始化
```
List list = Arrays.asList("a", "b");
List list = new ArrayList(){};
```
### 知識點
* ArrayList自己實現了序列化和反序列化的方法,因為它自己實現了 private void writeObject\(java.io.ObjectOutputStream s\)和 private void readObject\(java.io.ObjectInputStream s\) 方法
* ArrayList基于數組方式實現,無容量的限制(會擴容)
* 添加元素時可能要擴容(所以最好預判一下),刪除元素時不會減少容量(若希望減少容量,trimToSize\(\)),刪除元素時,將刪除掉的位置元素置為null,下次gc就會回收這些元素所占的內存空間。添加刪除某個索引的數據時,需要整體移動數組所以效率比較低
* 線程不安全
* add\(int index, E element\):添加元素到數組中指定位置的時候,需要將該位置及其后邊所有的元素都整塊向后復制一位
* get\(int index\):獲取指定位置上的元素時,可以通過索引直接獲取(O\(1\))
* remove\(Object o\)需要遍歷數組
* remove\(int index\)不需要遍歷數組,只需判斷index是否符合條件即可,效率比remove\(Object o\)高
* contains\(E\)需要遍歷數組
* 使用iterator遍歷可能會引發多線程異常
* 中文排序
```
Collator collator = Collator.getInstance(Locale.CHINA);
List list = Arrays.asList("羅友寶", "黃慧", "阿偉", "車曉");
Collections.sort(list, collator);
list.stream().forEach(System.err::println);
```
- java演變
- JDK各個版本的新特性
- JDK1.5新特性
- JDK1.6新特性
- JDK1.7新特性
- JDK1.8新特性
- JAVA基礎
- 面向對象特性
- 多態
- 方法重載
- 方法重寫
- class
- 常量
- 訪問修飾符
- 類加載路徑
- java-equals
- 局部類
- java-hashCode
- Java類初始化順序
- java-clone方法
- JAVA對象實例化的方法
- 基礎部分
- JAVA基礎特性
- JAVA關鍵字
- javabean
- static
- 日期相關
- final
- interface
- 函數式接口
- JAVA異常
- 異常屏蔽
- try-with-resource資源泄露
- JAVA引用
- WeakReference
- SoftReference
- PhantomReference
- 位運算符
- try-with-resource語法糖
- JDK冷知識
- JAVA包裝類
- JAVA基本類型與包裝類
- java.lang.Boolean
- java.lang.Integer
- java.lang.Byte
- java.lang.Short
- java.lang.Long
- java.lang.Float
- java.lang.Double
- java.lang.Character
- 日期相關
- TemporalAdjusters
- String
- 字符串常量池
- String拼接
- String編譯期優化
- StringBuilder&StringBuffer
- intern
- 注解
- java標準注解
- 內置注解
- 元注解
- 自定義注解
- 注解處理器
- JVM注解
- Java8 Annotation新特性
- 反射-Reflective
- Reflection
- Class
- Constructor
- Method
- javabean-property
- MethodHandles
- 泛型
- 類型擦除
- bridge-method
- Accessor&Mutator方法
- enum
- JAVA數組
- finalize方法
- JAR文件
- JAVA高級編程
- CORBA
- JMX
- SPI
- Java SPI使用約定
- ServiceLoader
- 實際應用
- IO
- 工具類
- JDK常用工具類
- Objects
- System
- Optional
- Throwable
- Collections
- Array
- Arrays
- System
- Unsafe
- Number
- ClassLoader
- Runtime
- Object
- Comparator
- VarHandle
- 數據結構
- 棧-Stack
- 隊列(Queue)
- Deque
- PriorityQueue
- BlockingQueue
- SynchronousQueue
- ArrayBlockingQueue
- LinkedBlockingQueue
- PriorityBlockingQueue
- ConcurrentLinkedQueue
- 列表
- 迭代器
- KV鍵值對數據類型
- HashMap
- TreeMap
- Hash沖突
- ConcurrentHashMap
- JDK1.7 ConcurrentHashMap結構
- jdk7&jdk8區別
- 集合
- Vector
- Stack
- HashSet
- TreeSet
- ArrayList
- LinkedList
- ArrayList && LinkedList相互轉換
- 線程安全的集合類
- 集合類遍歷性能
- 并發容器
- CopyOnWriteArrayList
- ConcurrentHashMap
- 同步容器
- BitMap
- BloomFilter
- SkipList
- 設計模式
- 設計模式六大原則
- 單例模式
- 代理模式
- 靜態代理
- 動態代理
- JDK動態代理
- cglib動態代理
- spring aop
- 策略模式
- SpringAOP策略模式的運用
- 生產者消費者模式
- 迭代器模式
- 函數式編程
- 方法引用
- 性能問題
- Lambda
- Lambda類型檢查
- Stream
- findFirst和findAny
- reduce
- 原始類型流特化
- 無限流
- 收集器
- 并行流
- AOP
- 靜態織入
- aspect
- aspect的定義
- AspectJ與SpringAOP
- 動態織入
- 靜態代理
- 動態代理
- JDK動態代理
- CGLib動態代理
- Spring AOP
- SpringAOP五種通知類型
- @Before
- @AfterReturning
- @AfterThrowing
- @After
- @Around
- Aspect優先級
- SpringAOP切點表達式
- within
- execution
- 嵌套調用
- 系統優化與重構
- 重疊構造器模式
- 工具類構造器優化
- 常見面試題
- new Object()到底占用幾個字節
- 訪問修飾符
- cloneable接口實現原理
- 異常分類以及處理機制
- wait和sleep的區別
- 數組在內存中如何分配
- 類加載為什么要使用雙親委派模式,有沒有什么場景是打破了這個模式
- 類的實例化順序
- 附錄
- JAVA術語
- FAQ
- 墨菲定律
- 康威定律
- 軟件設計原則
- 阿姆達爾定律
- 字節碼工具
- OSGI