手動實現ArrayList動態陣列
手動實現動態陣列
作者q:2835916127
blog:博主部落格
線性表
資料結構: 計算機儲存組織資料的方式
線性表: 具有n個相同元素的有限序列(n>=0)
a1 -> a2 -> a3 -> a4 -> … -> an
a1: 首節點、(首元素)
an: 尾節點(尾元素)
- a1是a2的前驅節點
- a2是a1的後繼節點
常見的線性表:
- 陣列
- 連結串列
- 棧
- 佇列
- 雜湊表(雜湊表)
……
- 陣列是一種順序儲存的線性表,所有元素的記憶體地址是連續的
需要知道的一些
-
變數名是儲存在棧中的
-
new 出來的物件是儲存在堆中的
-
java中成員變數自動初始化,比如:
- int初始化為0
- 物件初始化為null
-
重寫toString()自定義列印陣列
-
StringBuilder可以拼接字串
Object[] ob = new Object[7];
- 物件陣列
- ob -> 棧空間
- ob[i] -> 堆空間
- ob[i] 裡並非物件本身,而是物件的引用(即地址)
int [] array = new int[10]{11,22,33};
例項:
背景: 在許多語言開發中陣列都有個致命缺點—陣列一旦建立,容量不可變,然而我們都希望陣列長度可以動態變化
需求 :底層採用陣列 實現動態擴容陣列(ArrayList)
目的:
- 體會線性結構
- 練習常用演算法
- 強化陣列
- 練習泛型
面對的問題:
- 陣列一旦建立,容量不可變
- 擴容的條件
- 如何處理空值
動態陣列介面設計
◼ int size(); // 元素的數量
◼ boolean isEmpty(); // 是否為空
◼ boolean contains(E element); // 是否包含某個元素
◼ void add(E element); // 新增元素到最後面
◼ E get(int index); // 返回index位置對應的元素
◼ E set(int index, E element); // 設定index位置的元素
◼ void add(int index, E element); // 往index位置新增元素
◼ E remove(int index); // 刪除index位置對應的元素
◼ int indexOf(E element); // 檢視元素的位置
◼ void clear(); // 清除所有元素
具體實現:
package cn.dreamyi.demo;
/**
* 動態可變陣列 自動擴容
* qq:2835916127
*/
public class DynamicArray<E> {
private int size = 0;//儲存當前元素長度
//定義預設初始化容量
private final int DEFAULT_CAPACITY = 10;
//查詢失敗返回值
private final int ELEMENT_NOt_FOUND = -1;
//用於儲存陣列元素
private E[] elements = (E[]) new Object[DEFAULT_CAPACITY];
/**
* 檢查索引越界
*
* @param index 當前訪問索引
*/
private void checkIndex(int index) {
if (index < 0 || index >= size) {
throw new IndexOutOfBoundsException("索引越界" + "允許範圍 size:0 => " + (size - 1) + " 當前索引:" + index);
}
}
/**
* 檢查新增索引越界
*
* @param index 新增位置的索引
*/
private void checkAddIndex(int index) {
if (index < 0 || index > size) {
throw new IndexOutOfBoundsException("索引越界" + "允許範圍 size:0 => " + (size) + " 當前索引:" + index);
}
}
/**
* 確保陣列容量夠用
*/
private void ensureCapacity() {
//擴容1.5倍
E[] newElements = (E[]) new Object[elements.length + (elements.length >> 1)];
for (int i = 0; i < size; i++) {
newElements[i] = elements[i];
}
elements = newElements;//引用
}
public DynamicArray() {
}
/**
* 帶參初始化
*
* @param capacity 初始化容量
*/
public DynamicArray(int capacity) {
if (capacity < 10) {
elements = (E[]) new Object[DEFAULT_CAPACITY];
} else {
elements = (E[]) new Object[capacity];
}
}
/**
* 返回當前元素的數量
*
* @return 當前元素的個數
*/
public int size() {
return size;
}
/**
* 當前陣列是否為空
* 空:true
* 非空:false
*
* @return 返回true | false
*/
public boolean isEmpty() {
return size == 0;
}
/**
* 是否包含某個元素
*
* @param element
* @return 返回true | false
*/
public boolean contains(E element) {
if (element == null) {
for (int i = 0; i < size; i++) {
if (elements[i] == null) return true;
}
} else {
for (int i = 0; i < size; i++) {
if (element.equals(elements[i])) return true;
}
}
return false;
}
/**
* 新增元素到尾部
*
* @param element 待新增的元素
*/
public void add(E element) {
if (size > elements.length - 1) {
ensureCapacity();
}
elements[size++] = element;
}
/**
* 返回對應索引的值 不存在返回-1
*
* @param index 元素的索引
* @return 對應值 | -1
*/
public E get(int index) {
checkIndex(index);
return elements[index];
}
/**
* 設定index位置元素的值
*
* @param index 需要設定的位置索引
* @param element 設定的值
* @return 返回原先的值
*/
public E set(int index, E element) {
checkIndex(index);//檢查索引越界
E old = elements[index];
elements[index] = element;
return old;
}
/**
* 向index位置新增元素
*
* @param index 插入位置的索引
* @param element 插入的元素
*/
public void add(int index, E element) {
checkAddIndex(index);//檢查索引越界
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) {
checkIndex(index);
E old = elements[index];
for (int i = index; i < size; i++) {
elements[i] = elements[i + 1];
}
elements[--size] = null;//清空最後一個元素
return old;
}
/**
* 查詢元素
*
* @param element 需要查詢的元素
* @return 返回該元素索引 | -1
*/
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;
}
/**
* 清空所有元素
*/
public void clear() {
for (int i = 0; i < size; i++) {
elements[i] = null;
}
}
/**
* 返回元素集合size:5, [1, 3, 4 ,5 ,7 ]
*
* @return
*/
@Override
public String toString() {
StringBuilder sb = new StringBuilder("size:" + size + " => [");
for (int i = 0; i < size; i++) {
if (i != 0) {
sb.append(" ,");
}
sb.append(elements[i]);
}
sb.append("]");
return sb.toString();
}
}
主函式中呼叫
public static void main(String[] args) {
// System.out.println(feb2(45));
DynamicArray<String> list = new DynamicArray(1);
list.add("sdas");
list.add("32143");
DynamicArray<Student> stuList = new DynamicArray<>();
Student st1 = new Student("001", "張三", "19");
Student st2 = new Student("002", "李四", "23");
Student st3 = new Student("001", "趙六", "25");
stuList.add(st1);
stuList.add(null);
System.out.println(stuList.contains(null));
System.out.println(stuList.indexOf(null));
stuList.add(st2);
stuList.add(st3);
System.out.println(stuList.toString());
// System.out.println(list.toString());
總結:見上面
相關文章
- 動手編寫—動態陣列(Java實現)陣列Java
- ArrayList動態陣列物件 c# 1231陣列物件C#
- 【JAVA】ArrayList手動實現(初級)Java
- 動態陣列陣列
- Java陣列如何實現動態初始化Java陣列
- 靜態動態陣列陣列
- 建立動態陣列陣列
- 動態陣列ArrayList的初始化,新增資料,與遍歷陣列
- 2-7 陣列:動態陣列陣列
- C++容器巢狀實現動態二維陣列C++巢狀陣列
- 陣列004 動態建立一維陣列陣列
- List介面(動態陣列)陣列
- shared_ptr和動態陣列陣列
- 資料結構與演算法系列2 線性表 使用java實現動態陣列+ArrayList原始碼詳解資料結構演算法Java陣列原始碼
- 靜態佇列,迴圈陣列實現佇列陣列
- 陣列容器(ArrayList)設計與Java實現,看完這個你不懂ArrayList,你找我!!!陣列Java
- 演算法基礎:動態規劃陣列中滾動陣列的使用演算法動態規劃陣列
- 基於 golang 實現的泛型陣列,支援動態擴容等特性Golang泛型陣列
- mORMot 1.18 第13章 動態陣列ORM陣列
- AUTOCAD——拉伸陣列組合動態塊陣列
- 純手寫實現JDK動態代理JDK
- [JAVA] Java 陣列、多維陣列,動態、靜態初始化,陣列JVM記憶體模型分析Java陣列JVM記憶體模型
- 自己動手實現一個阻塞佇列佇列
- C語言動態陣列小作業C語言陣列
- 堆疊的實現(1)--靜態陣列陣列
- Solidity中函式返回值,靜態動態陣列Solid函式陣列
- Bert結構手動矩陣運算實現(Transform)矩陣ORM
- DP 動態規劃入門 一維陣列動態規劃陣列
- C++基礎回顧4——動態陣列C++陣列
- 二維陣列動態開闢與傳參陣列
- Python 實現 動態規劃 /斐波那契數列Python動態規劃
- 笨辦法學C 練習34:動態陣列陣列
- RDLC 動態列
- 動態棧的實現
- Feign實現動態URL
- 【乾貨】JDK動態代理的實現原理以及如何手寫一個JDK動態代理JDK
- (超詳細)動手編寫 — 棧、佇列 ( Java實現 )佇列Java
- 自己動手實現OkHttpHTTP