动态数组java实现
数组是一种顺序存储的线性表,所有元素的内存地址是连续的。
动态数组相对于一般数组的优势是可以灵活地添加或删除元素。而一般数组则受限于固定的内存空间。只能有限的添加元素
动态数组(Dynamic Array)接口设计
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(); // 清除所有元素
上代码:
动态数组类的实现:
public class ArrayList<E> {
//动态数组至少应该有数组的长度和元素的索引两个成员变量。
/**
* 元素的数量
*/
private int size;
/**
* 所有的元素
*/
private E[] elements;
//在创建数组时要有一个初始的容量,容量的大小根据实际情况确定,避免重复申请或销毁内存。
private static final int DEFAULT_CAPACITY = 10;
//这里用来进行判定
private static final int ELEMENT_NOT_FOUND = -1;
public ArrayList(int capaticy) {
//如果实际需要的容量比默认容量小,就使用默认容量
capaticy = (capaticy < DEFAULT_CAPACITY) ? DEFAULT_CAPACITY : capaticy;
elements = (E[]) new Object[capaticy];
}
public ArrayList() {
this(DEFAULT_CAPACITY);
}
/**
* 清除所有元素
*/
public void clear() {
//为了使动态数组可以存储多种类型的元素使用了泛型
//这样的话new的数组里每个位置存储的是元素内存的索引
//这样清空的时候需要将每个内存的索引都必须清除
//否则内存中的元素依然可以被访问
for (int i = 0; i < size; i++) {
elements[i] = null;
}
//动态数组的使用过程中可能会反复的添加或删除元素,因此没有必要每次清空元素的时候都销毁数组所在的内存空间
//因为申请和销毁内存空间都是需要时间的
size = 0;
}
/**
* 元素的数量
* @return
*/
public int size() {
return size;
}
/**
* 是否为空
* @return
*/
public boolean isEmpty() {
return size == 0;
}
/**
* 是否包含某个元素
* @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];
}
/**
* 设置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位置插入一个元素
* @param index
* @param element
*/
public void add(int index, E element) {
//加这一行不允许存空值
//if(element==null)return;
//在插入元素之前先要判断输入的索引位置
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];
//需要往前挪的元素是index后一个到数组的最后一个
for (int i = index + 1; i < size; i++) {
elements[i - 1] = elements[i];
}
//size-1,之后将末尾的元素清空
elements[--size] = null;
return old;
}
/**
* 查看元素的索引
* @param element
* @return
*/
public int indexOf(E element) {
if (element == null) { // 1
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; // n
}
}
return ELEMENT_NOT_FOUND;
}
// public int indexOf2(E element) {
// for (int i = 0; i < size; i++) {
// if (valEquals(element, elements[i])) return i; // 2n
// }
// return ELEMENT_NOT_FOUND;
// }
//
// private boolean valEquals(Object v1, Object v2) {
// return v1 == null ? v2 == null : v1.equals(v2);
// }
/**
* 保证要有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;
System.out.println(oldCapacity + "扩容为" + newCapacity);
}
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() {
// size=3, [99, 88, 77]
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]);
// if (i != size - 1) {
// string.append(", ");
// }
}
string.append("]");
return string.toString();
}
}
动态数组java实现的更多相关文章
- 常用数据结构-线性表及Java 动态数组 深究
[Java心得总结六]Java容器中——Collection在前面自己总结的一篇博文中对Collection的框架结构做了整理,这里深究一下Java中list的实现方式 1.动态数组 In compu ...
- Java动态数组
其中java动态数组: Java动态数组是一种可以任意伸缩数组长度的对象,在Java中比较常用的是ArrayList,ArrayList是javaAPI中自带的java.util.ArrayList. ...
- JAVA数据结构--ArrayList动态数组
在计算机科学中,动态数组,可扩展数组,可调整数组,动态表,可变数组或数组列表是一种随机存取可变大小列表数据结构,允许添加或删除元素.它提供许多现代主流编程语言的标准库.动态数组克服了静态数组的限制,静 ...
- java动态数组笔记
动态数组: 在java.lang.reflect包下提供了Array类,包括一系列static方法,通过这些方法可动态的创建数组.给元素赋值.取出元素值等等 //理解数组引用——下面定义的objs数组 ...
- java——时间复杂度、动态数组
O(n)不一定小于O(n^2),要具体来看,而我们说的这种时间复杂度其实是渐进时间复杂度,描述的是n趋近于无穷的情况. 动态数组的时间复杂度: 添加操作:O(n) addLast()的均摊复杂度为O( ...
- 纯数据结构Java实现(1/11)(动态数组)
我怕说这部分内容太简单后,突然蹦出来一个大佬把我虐到哭,还是悠着点,踏实写 大致内容有: 增删改查,泛型支持,扩容支持,复杂度分析.(铺垫: Java语言中的数组) 基础铺垫 其实没啥好介绍的,顺序存 ...
- 三 基于Java动态数组手写队列
手写队列: package dataStucture2.stackandqueue; import com.lt.datastructure.MaxHeap.Queue; import dataStu ...
- 二 基于java动态数组手写栈
package dataStucture2.stack; import dataStucture2.array.MyDynamicArray; /** * 基于动态数组手写栈 * 设计时,栈中仅栈顶对 ...
- 一篇文章让你了解动态数组的数据结构的实现过程(Java 实现)
目录 数组基础简单回顾 二次封装数组类设计 基本设计 向数组中添加元素 在数组中查询元素和修改元素 数组中的包含.搜索和删除元素 使用泛型使该类更加通用(能够存放 "任意" 数据类 ...
随机推荐
- DJANGO-天天生鲜项目从0到1-001-环境框架搭建
本项目基于B站UP主‘神奇的老黄’的教学视频‘天天生鲜Django项目’,视频讲的非常好,推荐新手观看学习 https://www.bilibili.com/video/BV1vt41147K8?p= ...
- 21天学通C++(C++程序的组成部分)
C++程序被组织成类,而类由成员函数和成员变量组成. 本章学习: 1)C++程序的组成部分. 2)各部分如何协同工作. 3)函数及其用途. 4)基本输入输出操作. C++程序划分为两个部分,以#大头的 ...
- Bug--时区问题导致IDEA连接数据库失败
打开cmd进入mysql,设置 set global time_zone='+8:00';
- 仓库储存,存在添加减少,不存在插入ON DUPLICATE KEY UPDATE
原文链接:https://blog.csdn.net/qq_42269354/article/details/100589640 首先声明:ON DUPLICATE KEY UPDATE 为MySQL ...
- JS的执行上下文
定义 执行上下文时是代码执行时的环境,JS代码在运行前进行编译,那么会生成两部分,一部分是可执行的代码,而另一部分则是执行上下文. 发展 执行上下文所包含的内容是在不断的变化的.它主要分为了三个不同的 ...
- Skill 解决 Design Library 被识别成 Technology Library 的问题
https://www.cnblogs.com/yeungchie/ code procedure(ycTechLibToDesign(libName attachLibName) prog((lib ...
- 牛客IOI周赛17-提高组 卷积 生成函数 多项式求逆 数列通项公式
LINK:卷积 思考的时候 非常的片面 导致这道题没有推出来. 虽然想到了设生成函数 G(x)表示最后的答案的普通型生成函数 不过忘了化简 GG. 容易推出 \(G(x)=\frac{F(x)}{1- ...
- 加载Properties文件工具类:LoadConfig
import javax.servlet.http.HttpServletRequest; import javax.ws.rs.GET; import javax.ws.rs.Path; impor ...
- 焦点损失函数 Focal Loss 与 GHM
文章来自公众号[机器学习炼丹术] 1 focal loss的概述 焦点损失函数 Focal Loss(2017年何凯明大佬的论文)被提出用于密集物体检测任务. 当然,在目标检测中,可能待检测物体有10 ...
- mybatis plus 更新值为null的字段
转载请注明出处: 由于mybatis plus调用默认的更新操作方法时,不更新值为空,null或默认值等得属性字段,只更新值为非null,非空非默认值的属性字段. 以下为mybatis plus sa ...