欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java使用數(shù)組實現(xiàn)ArrayList的動態(tài)擴容的方法

 更新時間:2020年06月22日 10:57:09   作者:小梁coding  
這篇文章主要介紹了Java使用數(shù)組實現(xiàn)ArrayList的動態(tài)擴容的方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

提到數(shù)組大家肯定不會陌生,但我們也知道數(shù)組有個缺點就是在創(chuàng)建時就確定了長度,之后就不能更改長度。所以Java官方向我們提供了ArrayList這個可變長的容器。其實ArrayList底層也是用數(shù)組進行實現(xiàn)的,今天我們就自己使用數(shù)組實現(xiàn)ArrayList的功能。

一、整體框架

廢話不多說,我們以存放int類型元素為例,看一下ArrayList需要的成員變量和需要實現(xiàn)的方法。

public class ArrayList
 private int size;//用來記錄實際存儲元素個數(shù)
  private int[] elements;//用來存儲元素的數(shù)組
  
  //構(gòu)造方法:在創(chuàng)建ArrayList對象時,初始化elements數(shù)組
  public ArrayList(int capacity){
    elements = new int[capacity];
  }
 
 
 /**
 * 元素的數(shù)量
 * @return
 */
 public int size() {}
 /**
 * 是否為空
 * @return
 */
 public boolean isEmpty() {}
 /**
 * 查看元素的索引
 * @param element
 * @return
 */
 public int indexOf(int element) {}
 /**
 * 是否包含元素
 * @param element
 * @return
 */
 public boolean contains(int element) {}
 /**
 * 獲取index位置的元素
 * @param index
 * @return
 */
 public int get(int index) {}
 /**
 * 設(shè)置index位置的元素
 * @param index
 * @param element
 * @return 原來的元素
 */
 public int set(int index, int element) {}
 /**
 * 在index索引位置插入元素
 * @param index
 * @param element
 */
 public void add(int index, int element) {}
 /**
 * 添加元素到尾部
 * @param element
 */
 public void add(int element) {}
 /**
 * 刪除index位置的元素
 * @param index
 * @return
 */
 public int remove(int index) {}
 /**
 * 清除所有元素
 */
 public void clear() {}
 /**
 * 用來打印列表
 */
 public String toString() {}
  
}

二、方法實現(xiàn)

框架我們已經(jīng)有了,接下來我們一步步實現(xiàn)方法就行。

size()方法:

這個方法很簡單,因為我們有size屬性,直接將其返回就行了。

public int size() {
 return size;
}

isEmpty()方法:

這個方法也很簡單,判斷是否為空只需要判斷size是否為0即可。

public boolean isEmpty() {
 return size == 0;
}

indexOf(int element)方法:

這個方法是用來查詢元素的所在索引位置,并返回。我們通過遍歷列表查找即可,找到就將元素返回,沒有找到返回-1。

public int indexOf(int element) {
  
 for (int i = 0; i < size; i++) {
 if (element.equals(elements[i])) {
  return i;
 } 
 return -1; 
  
}

contains(int element)方法:

這個方法是用來查看所傳元素是否在數(shù)組中,我們可以直接通過indexOf()方法查看返回值是否不等于-1,不等于-1返回true,等于-1返回false。

public boolean contains(int element) {
 return indexOf(element) != -1;
}

get(int index)方法:

這個方法用來獲取指定索引位置的元素,我們直接返回數(shù)組的指定索引位置元素即可。

public int get(int index) {;
 return elements[index];
}

set(int index, int element)方法:

這個方法用來將指定索引位置元素改為指定元素,并將原來元素返回,我們通過數(shù)組索引獲取到該位置元素,并將指定元素賦值給該位置索引并將原來元素返回。

public int set(int index, int element) {
 int old = elements[index];
 elements[index] = element;
 return old;
}

add(int index, int element)方法:

個方法是在指定索引位置插入指定元素,我們首先將指定索引位置的元素以及之后所有的元素向后移動一位,然后再將指定元素賦值給數(shù)組的指定索引位置,最后并將size加1。

public void add(int index, int element) {

 for (int i = size; i > index; i--) {
 elements[i] = elements[i - 1];
 }
 elements[index] = element;
 size++;
 
}

add(int element)方法:

這個方法是在數(shù)組尾部添加元素,我們直接調(diào)用add(int index, int element)方法,將size作為index的參數(shù)傳入即可。

public void add(int element) {
 add(size, element);
}

remove(int index)方法:

這個方法用來刪除指定索引位置的元素,并將要刪除元素返回,我們首先通過指定索引獲取原來元素,當刪除該元素后需要將index索引后面的所有元素向前移動一位,最后將size減1。

public int remove(int index) {
 int old = elements[index];
 for (int i = index + 1; i < size; i++) {
 elements[i - 1] = elements[i]; 
 }
 size--; 
 
 return old;
}

clear()方法:

這個方法,用于清空數(shù)組中所有元素,我們只需要將size賦值為0即可。

public void clear() {

 size = 0;
}

toString()方法:

這個方法用于將所有元素打印出來,通過StringBuilder對象進行拼接,最后轉(zhuǎn)成字符串返回即可。

public String toString() {
 
 StringBuilder string = new StringBuilder();
 string.append("size=").append(size).append(", [");
 
 for (int i = 0; i < size; i++) {
  
 if (i != 0) {
  string.append(", ");
 }
 string.append(elements[i]);
 }
 
 
 string.append("]");
 return string.toString();
}

以上代碼基本實現(xiàn)了對數(shù)組的進行數(shù)據(jù)的增刪改查,但最后想達到我們的目的還要進一步優(yōu)化。

三、優(yōu)化

1.實現(xiàn)動態(tài)擴容

當我們向數(shù)組中添加元素時,如果數(shù)組已經(jīng)滿了我們就需要就數(shù)組進行動態(tài)擴容。擴容的原理并不是真的對原數(shù)組進行增加內(nèi)存操作,而是重新創(chuàng)建一個更大的數(shù)組,并將原數(shù)組的元素賦給新的數(shù)組。我們聲明一個私有方法確保添加元素前數(shù)組的容量足夠。

private void ensureCapacity(int capacity) {
 int oldCapacity = elements.length;
 if (oldCapacity >= capacity) return;
 
 // 新容量為舊容量的1.5倍
 int newCapacity = oldCapacity + (oldCapacity >> 1);
 int[] newElements = new int[newCapacity];
 for (int i = 0; i < size; i++) {
 newElements[i] = elements[i];
 }
 elements = newElements;

}

我們在add()方法中首先調(diào)用ensureCapacity(int capacity)方法進行判斷數(shù)組容量是否足夠,不夠進行擴容。

public void add(int index, E element) {
 
 ensureCapacity(size + 1);
 
 for (int i = size; i > index; i--) {
 elements[i] = elements[i - 1];
 }
 elements[index] = element;
 size++;
}

2. 確保索引不越界

當我們在調(diào)用傳入索引的方法時,首先要保證傳入索引在可用范圍內(nèi),不然會出現(xiàn)角標越界的異常。
定義outOfBound()方法,用于拋出角標越界異常信息。

private void outOfBounds(int index) {
 throw new IndexOutOfBoundsException("Index:" + index + ", Size:" + size);
}

定義rangeCheck()方法用于檢查索引是否越界,如果越界,調(diào)用outOfBound()拋出異常。

private void rangeCheck(int index) {
 if (index < 0 || index >= size) {
 outOfBounds(index);
 }
}

而對于調(diào)用add()方法時所傳入的索引范圍可以取到size位置,我們在定義一個rangeCheckForAdd()方法,用于檢查調(diào)用add()方法時索引是否越界。

private void rangeCheckForAdd(int index) {
 if (index < 0 || index > size) {
 outOfBounds(index);
 }
}

在get()方法,set()方法和remove()方法中,先調(diào)用rangeCheck()方法,檢查傳入索引是否越界。

public int get(int index) {
 rangeCheck(index);
 return elements[index];
}

public int set(int index, E element) {
 rangeCheck(index);
 
 int old = elements[index];
 elements[index] = element;
 return old;
}

public int remove(int index) {
 rangeCheck(index);
 
 int old = elements[index];
 for (int i = index + 1; i < size; i++) {
 elements[i - 1] = elements[i];
 }
 size--;
 return old;
}

3. 設(shè)置常量以及重寫構(gòu)造方法

對于類中的常數(shù)我們更希望封裝成常量,并且聲明一個默認容量,希望在創(chuàng)建對象時未傳入容量參數(shù)或傳入容量參數(shù)過小直接創(chuàng)建一個相對大小合適的數(shù)組。

private static final int DEFAULT_CAPACITY = 10;//我們將默認容量設(shè)為10
private static final int ELEMENT_NOT_FOUND = -1;//我們將獲取指定元素的索引時,未找到的返回值-1封裝為常量

//聲明無參構(gòu)造方法,在調(diào)用無參構(gòu)造方法是直接創(chuàng)建默認容量的數(shù)組
public ArrayList(){
  elements = new int[DEFAULT_CAPACITY];
}

//聲明有參構(gòu)造方法,在傳入?yún)?shù)小于默認容量時,我們?nèi)匀粍?chuàng)建默認容量數(shù)組
public ArrayList(int capaticy) {
 capaticy = (capaticy < DEFAULT_CAPACITY) ? DEFAULT_CAPACITY : capaticy;
 elements = new int[capaticy];
}

四、使用泛型

以上步驟已經(jīng)使用數(shù)組完全實現(xiàn)了ArrayList的全部功能,但只能存放int類型的數(shù)據(jù),如果我們希望儲存其他類型的數(shù)據(jù)我們只需要使用Java中的泛型就能夠完成。

思路與上述完全一樣,整體代碼如下:

public class ArrayList<E> {
 /**
 * 元素的數(shù)量
 */
 private int size;
 /**
 * 所有的元素
 */
 private E[] elements;
 
 private static final int DEFAULT_CAPACITY = 10;
 private static final int ELEMENT_NOT_FOUND = -1;
 
 public ArrayList() {
 elements = (E[]) new Object[DEFAULT_CAPACITY];
 }
 
 public ArrayList(int capaticy) {
 capaticy = (capaticy < DEFAULT_CAPACITY) ? DEFAULT_CAPACITY : capaticy;
 elements = (E[]) new Object[capaticy];
 }
 
 
 /**
 * 清除所有元素
 */
 public void clear() {
 for (int i = 0; i < size; i++) {
  elements[i] = null;
 }
 size = 0;
 }

 /**
 * 元素的數(shù)量
 * @return
 */
 public int size() {
 return size;
 }

 /**
 * 是否為空
 * @return
 */
 public boolean isEmpty() {
  return size == 0;
 }

 /**
 * 是否包含某個元素
 * @param element
 * @return
 */
 public boolean contains(E element) {
 return indexOf(element) != ELEMENT_NOT_FOUND;
 }

 /**
 * 添加元素到尾部
 * @param element
 */
 public void add(E element) {
 add(size, element);
 }

 /**
 * 獲取index位置的元素
 * @param index
 * @return
 */
 public E get(int index) {
 rangeCheck(index);
 return elements[index];
 }

 /**
 * 設(shè)置index位置的元素
 * @param index
 * @param element
 * @return 原來的元素ֵ
 */
 public E set(int index, E element) {
 rangeCheck(index);
 
 E old = elements[index];
 elements[index] = element;
 return old;
 }

 /**
 * 在index位置插入一個元素
 * @param index
 * @param element
 */
 public void add(int index, E element) {
 rangeCheckForAdd(index);
 
 ensureCapacity(size + 1);
 
 for (int i = size; i > index; i--) {
  elements[i] = elements[i - 1];
 }
 elements[index] = element;
 size++;
 }

 /**
 * 刪除index位置的元素
 * @param index
 * @return
 */
 public E remove(int index) {
 rangeCheck(index);
 
 E old = elements[index];
 for (int i = index + 1; i < size; i++) {
  elements[i - 1] = elements[i];
 }
 elements[--size] = null;
 return old;
 }

 /**
 * 查看元素的索引
 * @param element
 * @return
 */
 public int indexOf(E element) {
 if (element == null) { 
  for (int i = 0; i < size; i++) {
  if (elements[i] == null) return i; 
  }
 } else {
  for (int i = 0; i < size; i++) {
  if (element.equals(elements[i])) return i; 
  }
 }
 return ELEMENT_NOT_FOUND;
 }
 
 
 /**
 * 保證要有capacity的容量
 * @param capacity
 */
 private void ensureCapacity(int capacity) {
 int oldCapacity = elements.length;
 if (oldCapacity >= capacity) return;
 
 // 新容量為舊容量的1.5倍
 int newCapacity = oldCapacity + (oldCapacity >> 1);
 E[] newElements = (E[]) new Object[newCapacity];
 for (int i = 0; i < size; i++) {
  newElements[i] = elements[i];
 }
 elements = newElements;

 }
 
 private void outOfBounds(int index) {
 throw new IndexOutOfBoundsException("Index:" + index + ", Size:" + size);
 }
 
 private void rangeCheck(int index) {
 if (index < 0 || index >= size) {
  outOfBounds(index);
 }
 }
 
 private void rangeCheckForAdd(int index) {
 if (index < 0 || index > size) {
  outOfBounds(index);
 }
 }
 
 @Override
 public String toString() {
 StringBuilder string = new StringBuilder();
 string.append("size=").append(size).append(", [");
 for (int i = 0; i < size; i++) {
  if (i != 0) {
  string.append(", ");
  }
  
  string.append(elements[i]);
 } 
 string.append("]");
 return string.toString();
 }
}

到此這篇關(guān)于Java使用數(shù)組實現(xiàn)ArrayList的動態(tài)擴容的方法的文章就介紹到這了,更多相關(guān)Java ArrayList動態(tài)擴容內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • spring用戶通過交互界面登錄成功的實現(xiàn)

    spring用戶通過交互界面登錄成功的實現(xiàn)

    本文主要介紹了spring用戶通過交互界面登錄成功的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-07-07
  • Struts2開發(fā)環(huán)境搭建 附簡單登錄功能實例

    Struts2開發(fā)環(huán)境搭建 附簡單登錄功能實例

    這篇文章主要介紹了Struts2開發(fā)環(huán)境搭建,為大家分享一個簡單登錄功能實例,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-11-11
  • Java實戰(zhàn)之超市收銀管理系統(tǒng)的實現(xiàn)

    Java實戰(zhàn)之超市收銀管理系統(tǒng)的實現(xiàn)

    這篇文章主要介紹了如何利用Java實現(xiàn)超市收銀管理系統(tǒng),文中采用的技術(shù)有:Spring、SpringMVC、MyBatis、ThymeLeaf等,需要的可以參考一下
    2022-03-03
  • 枚舉java語言中的修飾符組合的實例代碼

    枚舉java語言中的修飾符組合的實例代碼

    這篇文章主要介紹了枚舉java語言中的修飾符組合,本文通過實例代碼給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-07-07
  • Java實現(xiàn)簡單的飛機大戰(zhàn)游戲(控制主飛機篇)

    Java實現(xiàn)簡單的飛機大戰(zhàn)游戲(控制主飛機篇)

    這篇文章主要為大家詳細介紹了Java實現(xiàn)簡單的飛機大戰(zhàn)游戲,控制主飛機,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-05-05
  • java使用DOM4J對XML文件進行增刪改查操作

    java使用DOM4J對XML文件進行增刪改查操作

    這篇文章主要為大家詳細介紹了java使用DOM4J對XML文件進行增刪改查操作,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-12-12
  • springboot+thymeleaf+mybatis實現(xiàn)甘特圖的詳細過程

    springboot+thymeleaf+mybatis實現(xiàn)甘特圖的詳細過程

    這篇文章主要介紹了springboot+thymeleaf+mybatis實現(xiàn)甘特圖的詳細過程,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-07-07
  • 詳解Java面向?qū)ο笾械睦^承

    詳解Java面向?qū)ο笾械睦^承

    這篇文章主要介紹了詳解Java面向?qū)ο笾械睦^承,繼承提高代碼的復(fù)用性:通過繼承,子類可以直接使用父類的屬性和方法,不需要重復(fù)定義,需要的朋友可以參考下
    2023-05-05
  • Java虛擬機精選面試題20道

    Java虛擬機精選面試題20道

    現(xiàn)在面試Java開發(fā)時,基本都會問到Java虛擬機的知識,根據(jù)職位不同問的內(nèi)容深淺又有所區(qū)別。本文整理了10道面試中常問的Java虛擬機面試題,希望對正在面試的同學有所幫助
    2021-06-06
  • java求最大公約數(shù)與最小公倍數(shù)的方法示例

    java求最大公約數(shù)與最小公倍數(shù)的方法示例

    這篇文章主要介紹了java求最大公約數(shù)與最小公倍數(shù)的方法,涉及java數(shù)值運算的相關(guān)操作技巧,并附帶分析了eclipse環(huán)境下設(shè)置運行輸入?yún)?shù)的相關(guān)操作技巧,需要的朋友可以參考下
    2017-11-11

最新評論