Manually implement dynamic arrays
Author q: 2835916127
blog: blogger's blog
Linear table
Data structure: the way the computer stores and organizes data.
Linear table: a finite sequence with n identical elements (n>=0)
a1 -> a2 -> a3 -> a4 ->… -> an
a1: first node, (first element )
An: tail node (tail element)
- a1 is the predecessor node of a2
- a2 is the successor node of a1
Common linear tables:
- Array
- Linked list
- Stack
- queue
- Hash table (hash table)
...
- Array is a linear table stored sequentially, the memory addresses of all elements are consecutive
Some things to know
-
Variable names are stored on the stack
-
The new object is stored in the heap
-
Member variables in java are automatically initialized, such as:
- int is initialized to 0
- Object is initialized to null
-
Rewrite toString() to customize printing array
-
StringBuilder can splice strings
Object[] ob = new Object[7];
- Object array
- ob -> stack space
- ob[i] -> heap space
- Ob[i] is not the object itself, but the reference (ie address) of the object
int [] array = new int[10]{
11,22,33};
Examples:
Background: In the development of many languages, arrays have a fatal shortcoming-once the array is created, the capacity is immutable, but we all hope that the length of the array can change dynamically.
Requirements : The bottom layer uses an array to achieve the purpose of dynamically expanding the array (ArrayList)
:
- Experience the linear structure
- Practice common algorithms
- Enhanced array
- Practice generics
Problems faced:
- Once the array is created, the capacity is immutable
- Conditions for expansion
- How to deal with null values
Dynamic array interface design
◼ 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(); // 清除所有元素
Implementation:
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();
}
}
Called in the main function
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());