網(wǎng)上有很多關(guān)于pos機(jī)商城源碼,ArrayList 源碼解析的知識,也有很多人為大家解答關(guān)于pos機(jī)商城源碼的問題,今天pos機(jī)之家(m.afbey.com)為大家整理了關(guān)于這方面的知識,讓我們一起來看下吧!
本文目錄一覽:
pos機(jī)商城源碼
源碼環(huán)境: JDK 1.8
首先介紹讀源碼的方法,有些構(gòu)建的方法會將源碼整體編譯,造成卡頓,需要加大 Build process heap size。這里不將源碼拷貝到src,具體見韓順平的源碼閱讀配置視頻:韓順平源碼視頻,或者別人做的視頻截圖:自制截屏PPT。在寫注釋的時候,不要增刪行數(shù),以免 debug 時不匹配。
ArrayList 是一個可擴(kuò)容的動態(tài)數(shù)組,通常每次擴(kuò)大為原來的 1.5 倍。增刪慢,查找快。
1 主要屬性默認(rèn)大小為 10,使用 Object 類型的數(shù)組存儲數(shù)據(jù),size 表示數(shù)目,EMPTY_ELEMENTDATA 為空列表,另一個 DEFAULTCAPACITY_EMPTY_ELEMENTDATA 用于懶加載。
private static final int DEFAULT_CAPACITY = 10;transient Object[] elementData;// 數(shù)組存儲數(shù)據(jù)private int size;private static final Object[] EMPTY_ELEMENTDATA = {};// 空列表private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};// 區(qū)別于空列表,用于懶加載2 構(gòu)造器
一共三種構(gòu)造器,無參構(gòu)造器和大小為 0 的 Collection 構(gòu)造器使用了懶加載,初始為空列表,可以節(jié)省內(nèi)存,在 add 時才真正初始化 elementData。
public ArrayList(int initialCapacity) { if (initialCapacity > 0) { this.elementData = new Object[initialCapacity]; } else if (initialCapacity == 0) { this.elementData = EMPTY_ELEMENTDATA;// 空列表 } else { throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); } }public ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;// 懶加載 elementData }public ArrayList(Collection<? extends E> c) { elementData = c.toArray(); if ((size = elementData.length) != 0) { // 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;// 懶加載 elementData } }3 add以及擴(kuò)容3.1 add
一共有兩個 add 方法,沒有指定 index 會添加到最后,指定 index 的會在 index 處插入。
對于插入的方法,會首先將 index 及之后的元素向后移動 1 個位置,然后在 index 處放入 e。
public boolean add(E e) { ensureCapacityInternal(size + 1); // Increments modCount!! elementData[size++] = e; return true; }public void add(int index, E element) { rangeCheckForAdd(index); ensureCapacityInternal(size + 1); // Increments modCount!! System.arraycopy(elementData, index, elementData, index + 1, size - index);// 將 element[index] 及之后的元素后移一位 elementData[index] = element; size++; }private void rangeCheckForAdd(int index) { if (index > size || index < 0) throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); }/*** System 的方法,從 src[srcPos] 開始,移動到 dest[destPos],拷貝length個* 也就是從 src[srcPos] 到 src[srcPos + length - 1] 拷貝到 dest[destPos] 到 dest[destPos + length -1]。*/public static native void arraycopy(Object src, int srcPos, Object dest, int destPos, int length);3.2 addAll
addAll 方法同樣有兩個,對于單參數(shù)方法,采用的是 System.arraycopy 將 c 中的數(shù)據(jù)都添加到最后。
對于給定 index 的方法,則是兩次移動,先將原來 index 及后面的元素,向后移動 numNew 位,對于集合 c 中的元素,插入index 位置。
public boolean addAll(Collection<? extends E> c) { Object[] a = c.toArray(); int numNew = a.length; ensureCapacityInternal(size + numNew); // Increments modCount System.arraycopy(a, 0, elementData, size, numNew); size += numNew; return numNew != 0; }public boolean addAll(int index, Collection<? extends E> c) { rangeCheckForAdd(index); Object[] a = c.toArray(); int numNew = a.length; ensureCapacityInternal(size + numNew); // Increments modCount int numMoved = size - index; if (numMoved > 0) System.arraycopy(elementData, index, elementData, index + numNew, numMoved); System.arraycopy(a, 0, elementData, index, numNew); size += numNew; return numNew != 0; }3.3 擴(kuò)容相關(guān)
在正式執(zhí)行添加操作前,需要調(diào)用 ensureCapacityInternal(int minCapacity) 來保證 elementData 的長度大于等于 minCapacity,否則擴(kuò)容。
首先調(diào)用 calculateCapacity(Object[] elementData, int minCapacity),這里會處理初始化時懶加載的情況,如果不是就直接返回minCapacity。接著調(diào)用 ensureExplicitCapacity(int minCapacity) 判斷是否需要擴(kuò)容。如果擴(kuò)容 grow(minCapacity),則首先 newCapacity 擴(kuò)大為初始容量的 1.5 倍如果 minCapacity 大于 newCapacity,則 newCapacity 替換為 minCapacity。如果太大,超過了 MAX_ARRAY_SIZE,調(diào)用 hugeCapacity(int minCapacity)。調(diào)用 Arrays.copyOf(elementData, newCapacity) 返回新的 elementData。hugeCapacity(int minCapacity) 會判斷是否 overflow,是的話拋出異常。 否則根據(jù) minCapacity 和 MAX_ARRAY_SIZE 的大小返回 Integer.MAX_VALUE 或 MAX_ARRAY_SIZE。private void ensureCapacityInternal(int minCapacity) { ensureExplicitCapacity(calculateCapacity(elementData, minCapacity)); }private static int calculateCapacity(Object[] elementData, int minCapacity) { if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {// 如果懶加載,則 return Math.max(DEFAULT_CAPACITY, minCapacity); } return minCapacity; }private void ensureExplicitCapacity(int minCapacity) { modCount++; // overflow-conscious code if (minCapacity - elementData.length > 0) grow(minCapacity);// 擴(kuò)容 }private void grow(int minCapacity) { // overflow-conscious code int oldCapacity = elementData.length; int newCapacity = oldCapacity + (oldCapacity >> 1);// 擴(kuò)容為 1.5 倍 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); }private static int hugeCapacity(int minCapacity) { if (minCapacity < 0) // overflow throw new OutOfMemoryError(); return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE; }private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;4 remove
remove 包括兩種,一種是給定位置 index,另一種是給定要刪除的元素 o。
給定 index 刪除后,如果刪除的不是最后一個,需要將 index 后面的向前移動一位。
給定 o,對于 null 用 ==,對于非 null 用 equals。
從添加刪除的過程來看,如果不是在末尾操作,都需要移動一些元素,平均復(fù)雜度為 O(n)。
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; }public boolean remove(Object o) { // 對于 null 不能用 equals,需要單獨處理 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; }private void rangeCheck(int index) { if (index >= size) throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); }private void fastRemove(int index) {// 和remove的區(qū)別在于不用檢查 index 是否越界,以及不用返回。 modCount++; 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 }5 get/set
檢查 index 符合范圍后,直接在數(shù)組相應(yīng)位置取出或者修改。
public E get(int index) { rangeCheck(index); return elementData(index); }E elementData(int index) { return (E) elementData[index]; } public E set(int index, E element) { rangeCheck(index); E oldValue = elementData(index); elementData[index] = element; return oldValue; }6 迭代器
兩種迭代器,迭代器 Itr,列表迭代器 ListItr。
public Iterator<E> iterator() { return new Itr(); }public ListIterator<E> listIterator(int index) { if (index < 0 || index > size) throw new IndexOutOfBoundsException("Index: "+index); return new ListItr(index);// 從 index 開始的 ListItr }public ListIterator<E> listIterator() { return new ListItr(0); }6.1 迭代器
Itr 實現(xiàn)了迭代器的 next 和 hasNext 以及 remove。
Itr 有三個成員變量:cursor 是下一個要訪問的元素位置,lastRet 表示上次訪問的元素位置,初始和刪除后重置為-1, expectedModCount 負(fù)責(zé)檢查是否拋出 ConcurrentModificationException。
hasNext 判斷是否到達(dá)末尾, next 返回 cursor 處的元素,cursor向后移動, remove 調(diào)用 ArrayList 的方法刪除 lastRet 處的元素。
private class Itr implements Iterator<E> { int cursor; // index of next element to return int lastRet = -1; // index of last element returned; -1 if no such int expectedModCount = modCount; Itr() {} public boolean hasNext() { return cursor != size; } @SuppressWarnings("unchecked") public E next() { checkForComodification(); int i = cursor; if (i >= size) throw new NoSuchElementException(); Object[] elementData = ArrayList.this.elementData; if (i >= elementData.length) throw new ConcurrentModificationException(); cursor = i + 1; return (E) elementData[lastRet = i]; } public void remove() { if (lastRet < 0) throw new IllegalStateException(); checkForComodification(); try { ArrayList.this.remove(lastRet);// 刪除操作 cursor = lastRet; lastRet = -1; expectedModCount = modCount; } catch (IndexOutOfBoundsException ex) { throw new ConcurrentModificationException(); } } final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); } }6.2 列表迭代器
列表迭代器 ListItr 繼承了 Itr,實現(xiàn)了 ListIterator。
ListIterator 除了 next 的方法,還包括 previous 相關(guān)方法,返回索引 nextIndex/previousIndex 的方法,添加 add 修改 set 的方法。
nextIndex 就是 cursor,而 previousIndex 就是 cursor - 1,所以next 返回 cursor 處的元素并后移 cursor,previous 返回 cursor-1 處的元素并前移 cursor。
add 在 cursor 處插入,set 修改 lastRet 處元素。具體則調(diào)用 ArrayList 方法來操作。
private class ListItr extends Itr implements ListIterator<E> { ListItr(int index) { super(); cursor = index; } public boolean hasPrevious() { return cursor != 0;// cursor 為 0 ,cursor-1 越界 } public int nextIndex() { return cursor; } public int previousIndex() { return cursor - 1; } @SuppressWarnings("unchecked") public E previous() { checkForComodification(); int i = cursor - 1; if (i < 0) throw new NoSuchElementException(); Object[] elementData = ArrayList.this.elementData; if (i >= elementData.length) throw new ConcurrentModificationException(); cursor = i; return (E) elementData[lastRet = i]; } public void set(E e) { if (lastRet < 0) throw new IllegalStateException(); checkForComodification(); try { ArrayList.this.set(lastRet, e);// 修改操作 } catch (IndexOutOfBoundsException ex) { throw new ConcurrentModificationException(); } } public void add(E e) { checkForComodification(); try { int i = cursor; ArrayList.this.add(i, e);// 添加操作 cursor = i + 1; lastRet = -1; expectedModCount = modCount; } catch (IndexOutOfBoundsException ex) { throw new ConcurrentModificationException(); } } }
以上就是關(guān)于pos機(jī)商城源碼,ArrayList 源碼解析的知識,后面我們會繼續(xù)為大家整理關(guān)于pos機(jī)商城源碼的知識,希望能夠幫助到大家!
![](/style/images/zhouzong.jpg)