亚洲免费在线视频-亚洲啊v-久久免费精品视频-国产精品va-看片地址-成人在线视频网

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

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

瀏覽:3日期:2022-08-30 15:59:54

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

一、整體框架

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

public class ArrayList private int size;//用來記錄實(shí)際存儲(chǔ)元素個(gè)數(shù) private int[] elements;//用來存儲(chǔ)元素的數(shù)組 //構(gòu)造方法:在創(chuàng)建ArrayList對(duì)象時(shí),初始化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() {} }

二、方法實(shí)現(xiàn)

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

size()方法:

這個(gè)方法很簡(jiǎn)單,因?yàn)槲覀冇衧ize屬性,直接將其返回就行了。

public int size() { return size;}

isEmpty()方法:

這個(gè)方法也很簡(jiǎn)單,判斷是否為空只需要判斷size是否為0即可。

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

indexOf(int element)方法:

這個(gè)方法是用來查詢?cè)氐乃谒饕恢?,并返回。我們通過遍歷列表查找即可,找到就將元素返回,沒有找到返回-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)方法:

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

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

get(int index)方法:

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

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

set(int index, int element)方法:

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

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

add(int index, int element)方法:

個(gè)方法是在指定索引位置插入指定元素,我們首先將指定索引位置的元素以及之后所有的元素向后移動(dòng)一位,然后再將指定元素賦值給數(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)方法:

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

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

remove(int index)方法:

這個(gè)方法用來刪除指定索引位置的元素,并將要?jiǎng)h除元素返回,我們首先通過指定索引獲取原來元素,當(dāng)刪除該元素后需要將index索引后面的所有元素向前移動(dòng)一位,最后將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()方法:

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

public void clear() { size = 0;}

toString()方法:

這個(gè)方法用于將所有元素打印出來,通過StringBuilder對(duì)象進(jìn)行拼接,最后轉(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();}

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

三、優(yōu)化

1.實(shí)現(xiàn)動(dòng)態(tài)擴(kuò)容

當(dāng)我們向數(shù)組中添加元素時(shí),如果數(shù)組已經(jīng)滿了我們就需要就數(shù)組進(jìn)行動(dòng)態(tài)擴(kuò)容。擴(kuò)容的原理并不是真的對(duì)原數(shù)組進(jìn)行增加內(nèi)存操作,而是重新創(chuàng)建一個(gè)更大的數(shù)組,并將原數(shù)組的元素賦給新的數(shù)組。我們聲明一個(gè)私有方法確保添加元素前數(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;}

我們?cè)赼dd()方法中首先調(diào)用ensureCapacity(int capacity)方法進(jìn)行判斷數(shù)組容量是否足夠,不夠進(jìn)行擴(kuò)容。

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. 確保索引不越界

當(dāng)我們?cè)谡{(diào)用傳入索引的方法時(shí),首先要保證傳入索引在可用范圍內(nèi),不然會(huì)出現(xiàn)角標(biāo)越界的異常。定義outOfBound()方法,用于拋出角標(biāo)越界異常信息。

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); }}

而對(duì)于調(diào)用add()方法時(shí)所傳入的索引范圍可以取到size位置,我們?cè)诙x一個(gè)rangeCheckForAdd()方法,用于檢查調(diào)用add()方法時(shí)索引是否越界。

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)造方法

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

private static final int DEFAULT_CAPACITY = 10;//我們將默認(rèn)容量設(shè)為10private static final int ELEMENT_NOT_FOUND = -1;//我們將獲取指定元素的索引時(shí),未找到的返回值-1封裝為常量//聲明無參構(gòu)造方法,在調(diào)用無參構(gòu)造方法是直接創(chuàng)建默認(rèn)容量的數(shù)組public ArrayList(){ elements = new int[DEFAULT_CAPACITY];}//聲明有參構(gòu)造方法,在傳入?yún)?shù)小于默認(rèn)容量時(shí),我們?nèi)匀粍?chuàng)建默認(rèn)容量數(shù)組public ArrayList(int capaticy) { capaticy = (capaticy < DEFAULT_CAPACITY) ? DEFAULT_CAPACITY : capaticy; elements = new int[capaticy];}

四、使用泛型

以上步驟已經(jīng)使用數(shù)組完全實(shí)現(xiàn)了ArrayList的全部功能,但只能存放int類型的數(shù)據(jù),如果我們希望儲(chǔ)存其他類型的數(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; } /** * 是否包含某個(gè)元素 * @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位置插入一個(gè)元素 * @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ù)組實(shí)現(xiàn)ArrayList的動(dòng)態(tài)擴(kuò)容的方法的文章就介紹到這了,更多相關(guān)Java ArrayList動(dòng)態(tài)擴(kuò)容內(nèi)容請(qǐng)搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!

標(biāo)簽: Java
相關(guān)文章:
主站蜘蛛池模板: 欧美一级毛片欧美大尺度一级毛片 | 日本三级香港三级人妇99视 | 亚洲偷偷| 久久国内精品自在自线观看 | 亚洲欧美一区二区久久香蕉 | 久久精品视频3 | 免费看国产精品久久久久 | 欧美jizz19性欧美 | 国产乱淫a∨片免费视频 | 极品美女一级毛片 | 亚洲视频三区 | 91aaa免费免费国产在线观看 | 欧美一级毛片在线看视频 | 久久www免费人成精品 | 一级视频免费观看 | 日本精品一区二区三区在线视频一 | 国产永久免费视频m3u8 | 在线视频 日韩 | 美女wc| 91国内在线 | 免费一级成人毛片 | 午夜国产亚洲精品一区 | 国产亚洲小视频 | 欧美人成a视频www | 欧美另类videosbestsex视频 | 日韩精品特黄毛片免费看 | 国产高清在线精品一区a | 在线视频自拍 | 亚洲视频99 | 92看片淫黄大片看国产片 | 欧美视频一区二区三区 | 欧美三级黄色大片 | 国产二区自拍 | 欧美同性videos在线可播放 | 偷看各类wc女厕嘘在线观看 | 一级毛片成人免费看免费不卡 | 成人精品视频一区二区在线 | 久久国产精品久久 | 国产黄色网 | 精品无码久久久久国产 | 免费高清不卡毛片在线看 |