JavaのコレクションArrayListの原理とソース_少しクラス(マルチショア・カレッジ)の配列の詳細な分析

ArrayListのソースコード解析

  1. アレイはじめに

    配列は、データ構造が組み込まれていアレー多くのプログラミング言語の基本的な構造です。

    メモリ内の連続したメモリのアレイを作成する場合、それは、Javaで分割され、データがこのメモリに連続する順序で格納されているときにデータが入力される場合。データが配列に読み込まれる必要がある場合、配列は、インデックスを提供する必要があり、およびインデックス配列がメモリ内のデータを取り出しますが、プログラムは、読者に戻ります。Javaでは、全てのデータを配列に格納することができない、データの唯一の同じタイプは、一緒にアレイに記憶することができます。

    IMG

    データを順次データを格納するためのメモリに格納された配列に格納されているため連続しているので、彼がすることを特徴とする、読み取り挿入し、より困難削除しやすいデータをアドレス指定します

  2. ArrayListのソースコード解析

    • コンストラクタ

      public ArrayList(int initialCapacity) {
          if (initialCapacity > 0) {
              // 创建指定长度的object数组
              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;
      }
      
      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;
          }
      }
    • データの挿入

      public boolean add(E e) {
          // 检测是否需要扩容
          ensureCapacityInternal(size + 1);  // Increments modCount!!
          // 数组赋值
          elementData[size++] = e;
          return true;
      }
      
      public void add(int index, E element) {
          // 判断index是否越界
          rangeCheckForAdd(index);
          // 检测是否需要扩容
          ensureCapacityInternal(size + 1);  // Increments modCount!!
          // 将index之后的所有元素向后移动一位
          System.arraycopy(elementData, index, elementData, index + 1,
                           size - index);
          // 将index位置覆盖新值
          elementData[index] = element;
          size++;
      }
      
      // 扩容的入口方法
      private void ensureCapacityInternal(int minCapacity) {
          ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
      }
      
      // 计算最小容量
      private static int calculateCapacity(Object[] elementData, int minCapacity) {
          if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
              // 默认容量10
              return Math.max(DEFAULT_CAPACITY, minCapacity);
          }
          return minCapacity;
      }
      
      private void ensureExplicitCapacity(int minCapacity) {
          modCount++;
      
          // overflow-conscious code
          // 是否满足扩容的条件 最小容量 - object数组的长度
          if (minCapacity - elementData.length > 0)
              grow(minCapacity);
      }
      // 数组扩容方法
      private void grow(int minCapacity) {
          // overflow-conscious code
          // 当前数组长度
          int oldCapacity = elementData.length;
          // 新的数组容量 = 老容量 + 老容量/2 (1.5倍)
          // oldCapacity = 10
          // oldCapacity >> 1 
          //  0000 1010 >> 1 
          //  0000 0101 = 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:
          elementData = Arrays.copyOf(elementData, newCapacity);
      }
    • メソッドの削除

      // 指定位置删除
      public E remove(int index) {
          // 检测index值,IndexOutOfBoundsException
          rangeCheck(index);
      
          modCount++;
          // 返回要删除的元素
          E oldValue = elementData(index);
         // 将index+1及之后的元素向前移动一位,覆盖被删除的值
          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
          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;
                  }
          }
          // 如果没有匹配元素,返回false
          return false;
      }
      
      // 快速删除,没有检测index下标
      private void fastRemove(int 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
      }
    • トラバーサル

      ArrayList<Integer> list = new ArrayList();
      
      list.add(10);
      list.add(11);
      list.add(12);
      list.add(13);
      list.add(15);
      
      for (Integer num : list) {
          if (num == 12) {
              list.remove(num);
          }
      }
      // 报错
      // Exception in thread "main" java.util.ConcurrentModificationException
      
      final void checkForComodification() {
          // 不相等就报异常
          if (modCount != expectedModCount)
              throw new ConcurrentModificationException();
      }
      
      // 解决删除异常问题
      Iterator<Integer> it = list.iterator();
      while(it.hasNext()){
          Integer num = it.next();
          if (num == 12) {
              // 使用迭代器的删除方法
              it.remove();
          }
      }
      public void remove() {
          if (lastRet < 0)
              throw new IllegalStateException();
          checkForComodification();
      
          try {
              ArrayList.this.remove(lastRet);
              cursor = lastRet;
              lastRet = -1;
              // 修改expectedModCount和当前modCount一样
              expectedModCount = modCount;
          } catch (IndexOutOfBoundsException ex) {
              throw new ConcurrentModificationException();
          }
      }

    ビデオチュートリアル:http://www.yidiankt.com/

    リトル公共教室号
    国民の関心の数-コア知識[JAVA]に自由にアクセス!
    QQのディスカッション・グループ:706 564 342
    ここに画像を挿入説明

おすすめ

転載: www.cnblogs.com/yidiankt/p/11458052.html