ArrayList实现
生活随笔
收集整理的這篇文章主要介紹了
ArrayList实现
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
ArrayList實現 數組實現
父類:AbstractList
接口:List,RandomAccess,Cloneable,Serializable
字段:
//默認容量
private static final int DEFAULT_CAPACITY = 10;
//空的數組,構造函數參數為0和trim中使用,構造參數給0的人絕對會被打死,每放一個元素,就要重新copy一次
private static final Object[] EMPTY_ELEMENTDATA = {};
//實際保存數組,transient,這個字段不用寫入流
transient Object[] elementData
//實際元素數目
private int size;
public ArrayList(int initialCapacity) {if (initialCapacity > 0) {this.elementData = new Object[initialCapacity];} else if (initialCapacity == 0) {//注意初始容量為0時給的對象,EMPTY_ELEMENTDATAthis.elementData = EMPTY_ELEMENTDATA;}else {throw new IllegalArgumentException("Illegal Capacity: "+initialCapacity);}}public ArrayList(){//默認構造函數this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;}public ArrayList(Collection<? extends E> c) {//轉入的集合轉換為數組elementData = c.toArray();//改變自己的sizeif ((size = elementData.length) != 0) {//這里有個坑,可能不能正確的返回Object[] Class對象,不能的話復制// c.toArray might (incorrectly) not return Object[] (see 6260652)if (elementData.getClass() != Object[].class)elementData = Arrays.copyOf(elementData, size, Object[].class);} else {// replace with empty array.this.elementData = EMPTY_ELEMENTDATA;}}//截斷,在原數組上移動 public void trimToSize() {modCount++;if (size < elementData.length) {elementData = (size == 0)? EMPTY_ELEMENTDATA: Arrays.copyOf(elementData, size);}}//比較關心的幾個方法,存放,取出,查找 //查找,運行時間上界O(n),從這里也可用看出是允許放null public int indexOf(Object o) {if (o == null) {for (int i = 0; i < size; i++)if (elementData[i]==null)return i;} else {for (int i = 0; i < size; i++)if (o.equals(elementData[i]))return i;}return -1;}//反向查找public int lastIndexOf(Object o) {if (o == null) {for (int i = size-1; i >= 0; i--)if (elementData[i]==null)return i;} else {for (int i = size-1; i >= 0; i--)if (o.equals(elementData[i]))return i;}return -1;} //返回index位置的元素 E elementData(int index) {return (E) elementData[index];}//獲取對應位置元素,O(1)public E get(int index) {//檢查size,并沒有判斷小于0rangeCheck(index);return elementData(index); }//將元素放在對應位置,index<size,list當成數組使用,注意,這樣的代碼會報錯 //List<String> list = new ArrayList<>(100); // list.set(10, "123"); //根據構造函數可以知道,已經開辟了100長度的數組,但是就是不讓你用public E set(int index, E element) {rangeCheck(index);E oldValue = elementData(index);elementData[index] = element;return oldValue; }private void grow(int minCapacity) {// overflow-conscious codeint oldCapacity = elementData.length;//原來的1.5備長度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://注意是新開辟一個數組給elementDataelementData = Arrays.copyOf(elementData, newCapacity);}private void ensureExplicitCapacity(int minCapacity) {modCount++;// overflow-conscious code//1-0,進入if,進行內存復制,開辟新的數組if (minCapacity - elementData.length > 0)grow(minCapacity); }private void ensureCapacityInternal(int minCapacity) {//構造函數給0,這里是falseif (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);}//ensureExplicitCapacity(1);ensureExplicitCapacity(minCapacity);}//增加一個元素public boolean add(E e) {//為什么構造函數給0會被打死,看下面這個函數,一來就要新數組,新的數組長度也只有1ensureCapacityInternal(size + 1); // Increments modCount!!elementData[size++] = e;return true;}//元素放到index位置,0<=index<size public void add(int index, E element) {rangeCheckForAdd(index);ensureCapacityInternal(size + 1); // Increments modCount!!System.arraycopy(elementData, index, elementData, index + 1,size - index);elementData[index] = element;size++; } //移除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 workreturn oldValue; } //O(n)的移除,注意在fastRemove方法里面也會出現內存復制 public boolean remove(Object o) {if (o == null) {for (int index = 0; index < size; index++)if (elementData[index] == null) {fastRemove(index);return true;}} else {for (int index = 0; index < size; index++)if (o.equals(elementData[index])) {fastRemove(index);return true;}}return false;}//為什么elementData不用置null,方便重用 public void clear() {modCount++;// clear to let GC do its workfor (int i = 0; i < size; i++)elementData[i] = null;size = 0;}//淺克隆 public Object clone() {try {ArrayList<?> v = (ArrayList<?>) super.clone();v.elementData = Arrays.copyOf(elementData, size);v.modCount = 0;return v;} catch (CloneNotSupportedException e) {// this shouldn't happen, since we are Cloneablethrow new InternalError(e);}}//返回副本public Object[] toArray() {return Arrays.copyOf(elementData, size); }結尾附上一個內存分布的代碼,有指針真好 int main(int argc, char* argv[]) {//int ba[4];int a[] = { 1, 2, 3, 4 };int c = 5;int d = 6;int dd = 7;cout << a << endl;cout << a[-1] << endl;cout << a-1 << endl;cout<<&dd<<endl;cout << &d << endl;cout << &c << endl;//memcpy(ba, a, sizeof(int) * 4);//cout << ba[0] << endl;//cout << ba[1] << endl;return 0; }
父類:AbstractList
接口:List,RandomAccess,Cloneable,Serializable
字段:
//默認容量
private static final int DEFAULT_CAPACITY = 10;
//空的數組,構造函數參數為0和trim中使用,構造參數給0的人絕對會被打死,每放一個元素,就要重新copy一次
private static final Object[] EMPTY_ELEMENTDATA = {};
//實際保存數組,transient,這個字段不用寫入流
transient Object[] elementData
//實際元素數目
private int size;
public ArrayList(int initialCapacity) {if (initialCapacity > 0) {this.elementData = new Object[initialCapacity];} else if (initialCapacity == 0) {//注意初始容量為0時給的對象,EMPTY_ELEMENTDATAthis.elementData = EMPTY_ELEMENTDATA;}else {throw new IllegalArgumentException("Illegal Capacity: "+initialCapacity);}}public ArrayList(){//默認構造函數this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;}public ArrayList(Collection<? extends E> c) {//轉入的集合轉換為數組elementData = c.toArray();//改變自己的sizeif ((size = elementData.length) != 0) {//這里有個坑,可能不能正確的返回Object[] Class對象,不能的話復制// c.toArray might (incorrectly) not return Object[] (see 6260652)if (elementData.getClass() != Object[].class)elementData = Arrays.copyOf(elementData, size, Object[].class);} else {// replace with empty array.this.elementData = EMPTY_ELEMENTDATA;}}//截斷,在原數組上移動 public void trimToSize() {modCount++;if (size < elementData.length) {elementData = (size == 0)? EMPTY_ELEMENTDATA: Arrays.copyOf(elementData, size);}}//比較關心的幾個方法,存放,取出,查找 //查找,運行時間上界O(n),從這里也可用看出是允許放null public int indexOf(Object o) {if (o == null) {for (int i = 0; i < size; i++)if (elementData[i]==null)return i;} else {for (int i = 0; i < size; i++)if (o.equals(elementData[i]))return i;}return -1;}//反向查找public int lastIndexOf(Object o) {if (o == null) {for (int i = size-1; i >= 0; i--)if (elementData[i]==null)return i;} else {for (int i = size-1; i >= 0; i--)if (o.equals(elementData[i]))return i;}return -1;} //返回index位置的元素 E elementData(int index) {return (E) elementData[index];}//獲取對應位置元素,O(1)public E get(int index) {//檢查size,并沒有判斷小于0rangeCheck(index);return elementData(index); }//將元素放在對應位置,index<size,list當成數組使用,注意,這樣的代碼會報錯 //List<String> list = new ArrayList<>(100); // list.set(10, "123"); //根據構造函數可以知道,已經開辟了100長度的數組,但是就是不讓你用public E set(int index, E element) {rangeCheck(index);E oldValue = elementData(index);elementData[index] = element;return oldValue; }private void grow(int minCapacity) {// overflow-conscious codeint oldCapacity = elementData.length;//原來的1.5備長度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://注意是新開辟一個數組給elementDataelementData = Arrays.copyOf(elementData, newCapacity);}private void ensureExplicitCapacity(int minCapacity) {modCount++;// overflow-conscious code//1-0,進入if,進行內存復制,開辟新的數組if (minCapacity - elementData.length > 0)grow(minCapacity); }private void ensureCapacityInternal(int minCapacity) {//構造函數給0,這里是falseif (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);}//ensureExplicitCapacity(1);ensureExplicitCapacity(minCapacity);}//增加一個元素public boolean add(E e) {//為什么構造函數給0會被打死,看下面這個函數,一來就要新數組,新的數組長度也只有1ensureCapacityInternal(size + 1); // Increments modCount!!elementData[size++] = e;return true;}//元素放到index位置,0<=index<size public void add(int index, E element) {rangeCheckForAdd(index);ensureCapacityInternal(size + 1); // Increments modCount!!System.arraycopy(elementData, index, elementData, index + 1,size - index);elementData[index] = element;size++; } //移除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 workreturn oldValue; } //O(n)的移除,注意在fastRemove方法里面也會出現內存復制 public boolean remove(Object o) {if (o == null) {for (int index = 0; index < size; index++)if (elementData[index] == null) {fastRemove(index);return true;}} else {for (int index = 0; index < size; index++)if (o.equals(elementData[index])) {fastRemove(index);return true;}}return false;}//為什么elementData不用置null,方便重用 public void clear() {modCount++;// clear to let GC do its workfor (int i = 0; i < size; i++)elementData[i] = null;size = 0;}//淺克隆 public Object clone() {try {ArrayList<?> v = (ArrayList<?>) super.clone();v.elementData = Arrays.copyOf(elementData, size);v.modCount = 0;return v;} catch (CloneNotSupportedException e) {// this shouldn't happen, since we are Cloneablethrow new InternalError(e);}}//返回副本public Object[] toArray() {return Arrays.copyOf(elementData, size); }結尾附上一個內存分布的代碼,有指針真好 int main(int argc, char* argv[]) {//int ba[4];int a[] = { 1, 2, 3, 4 };int c = 5;int d = 6;int dd = 7;cout << a << endl;cout << a[-1] << endl;cout << a-1 << endl;cout<<&dd<<endl;cout << &d << endl;cout << &c << endl;//memcpy(ba, a, sizeof(int) * 4);//cout << ba[0] << endl;//cout << ba[1] << endl;return 0; }
?
posted on 2017-09-10 23:27 好吧,就是菜菜 閱讀(...) 評論(...) 編輯 收藏轉載于:https://www.cnblogs.com/shuiyonglewodezzzzz/p/7502877.html
總結
以上是生活随笔為你收集整理的ArrayList实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: windows远程连接linux-安装x
- 下一篇: 【Solidity】3.类型 - 深入理