1. 程式人生 > 其它 >使用原生JS實現一個英雄類Hero, 可以按照以下方式呼叫

使用原生JS實現一個英雄類Hero, 可以按照以下方式呼叫

ArrayList

            是基於陣列實現的,所以支援快速隨機訪問。

RandomAccess:標識該類支援快速隨機訪問

         public class ArrayList<E> extends AbstractList<E>   implements List<E>, RandomAccess, Cloneable, java.io.Serializable

陣列預設大小:10

         private static final int DEFAULT_CAPACITY = 10;

擴容機制

public boolean add(E e) {
  ensureCapacityInternal(size + 1);
  elementData[size++] = e;
  return true;
}

新增元素時確認容量大小: ensureCapacityInternal()

private void ensureCapacityInternal(int minCapacity) {
   if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
       minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
    }
  ensureExplicitCapacity(minCapacity);
}
private void ensureExplicitCapacity(int minCapacity) {
   modCount++;
   // overflow-conscious code
   if (minCapacity - elementData.length > 0)
       grow(minCapacity);
}

容量不夠,擴容: grow()

擴容後的容量:舊容量的1.5倍:oldCapacity + (oldCapacity >> 1)

private void grow(int minCapacity) {
   // overflow-conscious code
   int oldCapacity = elementData.length;
   int newCapacity = oldCapacity + (oldCapacity >> 1);  //擴容為原來的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); // 擴容操作要呼叫Arrays.copyOf() 把原陣列複製到新陣列中,但代價高效率低
//一般先指定ArrayList的容量大小,減少擴容操作次數。
}

刪除操作

呼叫System.arraycopy() :  將index+1後的元素複製從index上開始的位置

                                             操作時間複雜度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;
}

序列化

ArrayList基於陣列實現,具有動態擴容機制,儲存的元素不一定都會被使用,沒必要全部進行序列化。

不序列化:儲存元素的陣列 elementData 使用 transient 修飾(transient:預設不會被序列化。)

transient Object[] elementData; 
// non-private to simplify nested class access

控制序列化陣列中的元素內容的方法:writeObject() readObject()

//readObject()
private void readObject(java.io.ObjectInputStream s)
            throws java.io.IOException, ClassNotFoundException {
   elementData = EMPTY_ELEMENTDATA;
   // Read in size, and any hidden stuff
   s.defaultReadObject();
   // Read in capacity
   s.readInt(); // ignored
   if (size > 0) {
       // be like clone(), allocate array based upon size not capacity
       ensureCapacityInternal(size);
       Object[] a = elementData;
       // Read in all elements in the proper order.
       for (int i=0; i<size; i++) {
           a[i] = s.readObject();
      }
  }
}
//writeObject()
private void writeObject(java.io.ObjectOutputStream s)
       throws java.io.IOException{
   // Write out element count, and any hidden stuff
   int expectedModCount = modCount;
   s.defaultWriteObject();
   // Write out size as capacity for behavioural compatibility with clone()
   s.writeInt(size);
   // Write out all elements in the proper order.
   for (int i=0; i<size; i++) {
       s.writeObject(elementData[i]);
  }
   if (modCount != expectedModCount) {
       throw new ConcurrentModificationException();
  }
}

序列化操作:使用 ObjectOutputStream 的 writeObject() 將物件轉換為位元組流並輸出

                      writeObject() 方法在傳入的物件存在 writeObject() 的時候會去反射呼叫該物件的 writeObject() 來實現序列化。

User user = new User();
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("heyuFile"));
oos.writeObject(user);

反序列化操作:ObjectInputStream 的 readObject() 方法

File file = new File("heyuFile");
ObjectInputStream  objectInputStream = new ObjectInputStream(new FileInputStream(file));
User user =(User)objectInputStream.readObject();

Fail-Fast 快速失敗:

在做系統設計的時候先考慮異常情況,一旦發生異常,直接停止並上報。

在系統設計中,快速失效系統一種可以立即報告任何可能表明故障的情況的系統。快速失效系統通常設計用於停止正常操作,而不是試圖繼續可能存在缺陷的過程。這種設計通常會在操作中的多個點檢查系統的狀態,因此可以及早檢測到任何故障。快速失敗模組的職責是檢測錯誤,然後讓系統的下一個最高級別處理錯誤。

ConcurrentModificationException異常(CMException):

當方法檢測到物件的併發修改,但不允許這種修改時就丟擲該異常

發生CMException,優先考慮fail-fast有關的情況,實際上這裡並沒有真的發生併發,只是Iterator使用了fail-fast的保護機制,只要他發現有某一次修改是未經過自己進行的,那麼就會丟擲異常。