手动实现动态数组
作者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());