Java ArrayList底層方法的實(shí)現(xiàn)深度解析
【前言】
ArrayList是Java集合框架中List接口的動態(tài)數(shù)組實(shí)現(xiàn),可以方便的存儲和操作數(shù)據(jù)。它提供了一系列方法,便于我們進(jìn)行增刪查改,這篇文章是進(jìn)行ArrayList的一個自我實(shí)現(xiàn),讓我們從底層更深度地理解ArrayList(順序表)
一、 定義ArrayList類
arr: 創(chuàng)建一個整型數(shù)組,用來存儲數(shù)據(jù);usedSize: 有效數(shù)據(jù),也就是真實(shí)的元素個數(shù);DEFAULT_CAPACITY:默認(rèn)數(shù)組容量MyArrayList():構(gòu)造方法,初始化數(shù)組長度為默認(rèn)的容量
public class MyArrayList implements IList{
private int[] arr;//存儲數(shù)據(jù)
private int usedSize;//有效數(shù)據(jù)個數(shù)
public static final int DEFAULT_CAPACITY = 10;//默認(rèn)數(shù)組容量
public MyArrayList(){
this.arr = new int[DEFAULT_CAPACITY];
}
二、常見方法實(shí)現(xiàn)
ArrayList的常見方法如下:

1.add(int data):新增元素,添加在數(shù)組后面
public void add(int data) {
//判斷順序表是否滿了
if (isFull()) {
//擴(kuò)容
grow();
}
//存儲
this.arr[this.usedSize] = data;
this.usedSize++;
}
public boolean isFull(){
return this.usedSize == this.arr.length;
}
public void grow(){
this.arr = Arrays.copyOf(this.arr,2*this.arr.length);
}
添加元素時,要先檢查數(shù)組是否已滿(
isFull()通過比較數(shù)組的長度和元素個數(shù)),如果滿了,就要進(jìn)行擴(kuò)容grow(),這里是copy兩倍的數(shù)組容量,然后再進(jìn)行存儲
2.add(int pos, int data):再pos位置添加元素
public void add(int pos, int data) {
//檢查是不是滿的
if(isFull()){
grow();
}
checkPos(pos,"add方法執(zhí)行的時候pos位置不合法");
//判斷是不是放在usedSize位置
if(pos == usedSize){
arr[pos] = data;
usedSize++;
return;
}
//如果放在前面,就要移動數(shù)據(jù)
for (int i = usedSize-1; i >= pos; i++) {
arr[i+1] = arr[i];
}
arr[pos] = data;
usedSize++;
}
private void checkPosAdd(int pos,String msg) {
if (pos < 0 || pos > usedSize) {
throw new PosIllegalityException(msg);
}
}

還是先要檢查容量是否已滿
isFull(),滿了就要進(jìn)行擴(kuò)容grow(),然后添加時,要先檢查pos位置是否合法,如上圖,pos < 0 || pos > usedSize就是不合法的,在這個范圍則會拋出我們自定義的PosIllegalityException異常,正常情況下進(jìn)行添加:將pos位置及后面的元素統(tǒng)統(tǒng)向后移動一個位置,為要添加的元素騰出位置,然后有效數(shù)據(jù)usedSize++
3.contains(int toFind):判斷是否包含某個元素
public boolean contains(int toFind) {
for (int i = 0; i < this.usedSize; i++) {
if(arr[i] == toFind){
return true;
}
}
return false;
}
使用for循環(huán)遍歷整個數(shù)組,if語句判斷當(dāng)前元素是否是你要找的元素toFind,是返回true,不是返回false
4.indexOf(int toFind):查找某個元素對應(yīng)的位置
public int indexOf(int toFind) {
for (int i = 0; i < this.usedSize; i++) {
if(arr[i] == toFind){
return i;
}
}
return -1;
}
同理:使用for循環(huán)遍歷整個數(shù)組,if語句判斷當(dāng)前元素是否是你要找的元素toFind,是返回對應(yīng)元素的下標(biāo)i,不是返回-1
5.get(int pos):獲取pos位置的元素
public int get(int pos) {
if(isEmpty()){
throw new EmptyListException("當(dāng)前順序表為空");
}
checkPos(pos,"get方法的pos位置不合法");
return arr[pos];
}
private void checkPos(int pos,String msg){
if (pos<0 || pos >= usedSize){
throw new PosIllegalityException(msg);
}
}
public boolean isEmpty(){
return usedSize == 0;
}
獲取元素,先檢查pos位置是否為空
isEmpty(),如果為空,拋出我們的自定義異常EmptyListException,然后檢查pos位置是否合法pos<0 || pos >= usedSize這個范圍就是不合法的,拋出我們的自定義異常PosIllegalityException,最后就可以返回pos位置的元素
6.set(int pos, int value):給pos位置的元素設(shè)為value
public void set(int pos, int value) {
if(isEmpty()){
throw new EmptyListException("當(dāng)前順序表為空");
}
checkPos(pos,"set方法執(zhí)行的時候pos位置不合法"+pos);
arr[pos] = value;
}
替換時要先檢查是否為空
isEmpty(),為空拋出自定義異常EmptyListException,不為空檢查pos位置是否合法,最后將給定的值替換指定的數(shù)組元素
7.remove(int toRemove):刪除第?次出現(xiàn)的關(guān)鍵字key
public void remove(int toRemove) {
if(isEmpty()){
throw new EmptyListException("當(dāng)前順序表為空");
}
//查找要刪除數(shù)據(jù)的下標(biāo)
int index = indexOf(toRemove);
if(index == -1){
System.out.println("沒有你要刪除的數(shù)據(jù)");
return;
}
for (int i = index; i < usedSize-1; i++) {
arr[i] = arr[i+1];
}
usedSize--;
}
//arr[usedSize] = null;如果是引用類型,需要手動置空

還是先檢查是否為空,然后可以通過
indexOf(toRemove)查找要刪除的元素,如果index == -1,則沒有你要刪除的元素,如果有,進(jìn)行覆蓋刪除,讓后面的元素逐一向前移動一個位置直到你要,直到覆蓋掉你要刪除的元素,最后將有效元素usedSize–
8.size():獲取順序表?度
public int size() {
return this.usedSize;
}
9.clear():清空順序表
public void clear(){
for (int i = 0; i < this.usedSize; i++) {
arr[i] = 0;
}
usedSize = 0;
}
三、總結(jié)
這篇文章只是從深度的實(shí)現(xiàn)了一下ArrayList提供的一系列方法,以便于更好地去理解和使用ArrayList,讓我們認(rèn)識到了,數(shù)據(jù)結(jié)構(gòu)的學(xué)習(xí)和使用,要考慮到所有方面,對我們的邏輯思維能力要求很高,同樣也會提高我們這方面的能力,相關(guān)的其他內(nèi)容后面會詳細(xì)道來
到此這篇關(guān)于Java ArrayList底層方法的自我實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Java ArrayList底層方法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
關(guān)于Java單個TCP(Socket)連接發(fā)送多個文件的問題
這篇文章主要介紹了關(guān)于Java單個TCP(Socket)連接發(fā)送多個文件的問題,每次我只能使用一個 Socket 發(fā)送一個文件,沒有辦法做到連續(xù)發(fā)送文件,本文來解決這個問題,需要的朋友可以參考下2023-04-04
JAVA使用ElasticSearch查詢in和not in的實(shí)現(xiàn)方式
今天小編就為大家分享一篇關(guān)于JAVA使用Elasticsearch查詢in和not in的實(shí)現(xiàn)方式,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2018-12-12
SpringMVC中@ModelAttribute與@RequestBody的區(qū)別及說明
這篇文章主要介紹了SpringMVC中@ModelAttribute與@RequestBody的區(qū)別及說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-11-11
SpringBoot整合Milvus的實(shí)現(xiàn)
本文主要介紹了SpringBoot整合Milvus的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-07-07
SpringBoot深入分析運(yùn)行原理與功能實(shí)現(xiàn)
我們發(fā)現(xiàn)springBoot程序開發(fā)比spring程序編寫起來容易的多。配置簡潔,依賴關(guān)系簡單,啟動運(yùn)行容易。那么結(jié)下了我們我們就要思考一下入門程序中的這些功能是怎么實(shí)現(xiàn)的2022-09-09

