您好,登錄后才能下訂單哦!
這篇文章主要介紹“Java如何自定義一個變長數組”的相關知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“Java如何自定義一個變長數組”文章能幫助大家解決問題。
主要功能點:
新建時可以指定容量大小,不指定時使用默認容量大小。
向數組中追加新元素,當超過容量時應該自動擴容。
向數組中指定位置添加新元素,需要考慮指定的下標是否越界,同樣也需要考慮擴容操作。
刪除末尾的元素,需要考慮縮小容量。
刪除指定位置元素,需要考慮指定的下標是否越界,同樣也需要考慮縮小容量。
修改特定位置的元素,需要考慮指定的下標是否越界。
以時間復雜度為O ( 1 ) O(1)O(1)獲取任意位置的元素,需要考慮指定的下標是否越界。
主要注意點:
擴容: 這里擴容2倍(ArrayList 是擴容 1.5 倍),擴容時新建一個2倍容量的新數組,然后將舊數組中的元素按順序拷貝到新數組。
縮容: 當數組中的元素個數 <= 0.25 * 容量時,自動縮小容量為原來的一半,新建一個容量是原來容量一半的數組,然后將舊數組中的元素按順序拷貝到新數組。(ArrayList縮小為和當前元素個數一樣大)。
指定位置添加: 需要先將指定位置及后面所有的元素都向后移動一位,將指定位置空出來然后再插入。
指定位置刪除: 先將制定位置刪除,然后將后面的所有元素都向前移動一位。
容量大小: 需要指定容量的最大值,避免OOM的發生。最小值可以指定也可以不指定。
/** * 變長數組 * */ public class ResizeableArray<E> { private static final int MIN_CAPACITY = 10; private static final int MAX_CAPACITY = Integer.MAX_VALUE - 8; // 當前實際數據大小 private int size = 0; // 實際存放元素的數組,容量為 elements.length private Object[] elements; public ResizeableArray(){ this(MIN_CAPACITY); } public ResizeableArray(int initCapacity){ if(initCapacity < MIN_CAPACITY){ initCapacity = MIN_CAPACITY; }else if(initCapacity > MAX_CAPACITY){ initCapacity = MAX_CAPACITY; } this.elements = new Object[initCapacity]; } // 數組的特性,根據下標獲取元素 public E get(int index){ this.checkIndex(index); return (E)elements[index]; } // 添加一個元素到最后 public void add(E element){ if(size == elements.length){ // 需要擴容 this.expandCapacity(); } elements[size++] = element; } // 添加一個元素到指定位置 public void add(int index, E element){ if(index == size){ this.add(element); return; } this.checkIndex(index); if(size == elements.length){ // 需要擴容 this.expandCapacity(); } // 需要先將index和之后的所有元素向后移動一位 for(int i = size - 1; i >= index; i--){ elements[i + 1] = elements[i]; } elements[index] = element; size++; } // 設置下標為index的元素 private void set(int index, E element){ this.checkIndex(index); elements[index] = element; } /** * 刪除下標為index的元素 * 當 size <= 0.25 * capacity 的時候縮小容量 */ private void delete(int index){ this.checkIndex(index); elements[index] = null; // 如果刪除的不是最后一個元素,需要將后續元素往前移動一位 if(index < size - 1){ for(int i = index + 1; i < size; i++){ elements[i - 1] = elements[i]; } } size--; if(size <= 0.25 * elements.length){ this.reduceCapacity(); } } private void deleteLast(){ this.delete(size - 1); } private void checkIndex(int index){ if(index < 0 || index >= size){ throw new IndexOutOfBoundsException(String.format("Out of bounds at: %s, size is: %d", index, size)); } } private void expandCapacity(){ if(MAX_CAPACITY == elements.length){ // 容量達到最大限制,無法擴容。 throw new RuntimeException("The capacity has reached its maximum limit and cannot be expanded."); } int newCapacity = Math.min(elements.length << 1, MAX_CAPACITY); Object[] newElements = new Object[newCapacity]; System.arraycopy(elements, 0, newElements, 0, size); elements = newElements; } private void reduceCapacity(){ if(elements.length == MIN_CAPACITY){ return; } int newCapacity = Math.max(elements.length >> 1, MIN_CAPACITY); Object[] newElements = new Object[newCapacity]; System.arraycopy(elements, 0, newElements, 0, size); elements = newElements; } public static void main(String[] args){ ResizeableArray<Integer> resizeableArray = new ResizeableArray<>(); System.out.printf("初始化后,size為: %d \n", resizeableArray.size); System.out.printf("初始化后,capacity為: %d \n", resizeableArray.elements.length); System.out.println(); for(int i = 0; i < 20; i++){ resizeableArray.add(i); } System.out.printf("添加20個元素后,size為: %d \n", resizeableArray.size); System.out.printf("添加20個元素后,capacity為: %d \n", resizeableArray.elements.length); System.out.printf("添加20個元素后,第5個元素是: %d \n", resizeableArray.get(4)); System.out.println(); resizeableArray.delete(4); System.out.printf("刪除第五個元素后,size為: %d \n", resizeableArray.size); System.out.printf("刪除第五個元素后,capacity為: %d \n", resizeableArray.elements.length); System.out.printf("刪除第五個元素后,第5個元素是: %d\n", resizeableArray.get(4)); System.out.println(); resizeableArray.add(4, 100); System.out.printf("在第五個位置插入元素后,size為: %d \n", resizeableArray.size); System.out.printf("在第五個位置插入元素后,capacity為: %d \n", resizeableArray.elements.length); System.out.printf("在第五個位置插入元素后,第5個元素是: %d\n", resizeableArray.get(4)); System.out.println(); for(int i = 0; i < 15; i++){ resizeableArray.deleteLast(); } System.out.printf("刪除后面15個元素后,size為: %d \n", resizeableArray.size); System.out.printf("刪除后面15個元素后,capacity為: %d \n", resizeableArray.elements.length); System.out.printf("刪除后面15個元素后,第5個元素是: %d\n", resizeableArray.get(4)); System.out.println(); resizeableArray.set(4, 200); System.out.printf("修改第五個元素后,當前size為: %d \n", resizeableArray.size); System.out.printf("修改第五個元素后,capacity為: %d \n", resizeableArray.elements.length); System.out.printf("修改第五個元素后,第5個元素是: %d\n", resizeableArray.get(4)); } }
由執行結果可知:
初始化后默認容量為10
。
添加元素超過10
個后會自動擴容。
刪除一個元素后,size
會減1
,后面元素會自動向前移動一位。
插入一個新元素后,size
會加1
,后續元素后移一位。
刪除到只有0.25 * 容量
個元素后,會自動縮小容量。
關于“Java如何自定義一個變長數組”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識,可以關注億速云行業資訊頻道,小編每天都會為大家更新不同的知識點。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。