网站首页 > java教程 正文
我们都知道java提供的数组一旦初始化后,长度是固定的无法进行扩容。所以今天我们对数组进行封装重新编写一个更强大的数组(也可以看做简单版ArrayList)
//定义一个数组类 public class Array<E> { //默认数组 private E [] data; //数组元素个数 private int size; //初始化指定容量的构造函数 public Array(int initCapacity){ //java不支持直接new 泛型类型的数组所以需要进行类型转换 data = (E[]) new Object[initCapacity]; size = 0; } // 无参构造函数默认容量10 public Array(){ this(10); } //获取数组元素个数 public int getSize(){ return size; } //获取数组容量 public int getCapacity(){ return data.length; } //数组是否为空 public boolean isEmpty(){ return size == 0; } //向指定索引位置添加元素 public void add(int index,E e){ if(index < 0 || index > size){ //index < size是为了防止数组中间出现空隙,从而保证数组数据紧密连续的在一起 throw new IllegalArgumentException("array is error"); } if(size == data.length){ //插入数据时如果当前数组已满,需要对数组进行扩容,扩容现有数组的两倍而jdk是1.5倍 resize(2*data.length); } //在指定索引位置插入元素时,要将该位置及其后面的元素往后移动一个位置 for(int i = size - 1; i >= index; i--){ data[i + 1] = data[i]; } data[index] = e; size++; } //向数组末尾添加元素 public void addLast(E e){ add(size,e); } //向数组头部添加元素 public void addFirst(E e){ add(0,e); } //数组扩容,新建一个容量为原数组两倍的新数组,然后将原数组元素添加到新数组, //然后将新数组引用赋值给原数组 private void resize(int newCapacity){ E[] newData = (E[]) new Object[newCapacity]; for(int i = 0; i < size;i++){ newData[i] = data[i]; data = newData; } } //获取指定索引位置元素 public E get(int index){ if(index < 0 || index > size){ throw new IllegalArgumentException("index is illegal"); } return data[index]; } //修改元素 public void set(int index,E e){ if(index < 0 || index > size){ throw new IllegalArgumentException("index is illegal"); } data[index] = e; } //数组是否包含某个元素 public boolean contains(E e){ for(int i = 0; i < size; i++){ if(data[i].equals(e)){ return true; } } return false; } //查找数组元素e所在的索引,如果不存在则返回-1 public int find(E e){ for(int i = 0; i < size; i++){ if(data[i].equals(e)){ return i; } } return -1; } //删除指定索引位置的元素,并返回删除的元素 public E remove(int index){ if(index < 0 || index > size){ throw new IllegalArgumentException("index is illegal"); } E ret = data[index]; //删除指定位置索引同样需要移动其他元素 for(int i = index + 1; i < size; i++){ data[i-1] = data[i]; } //如果元素是引用类型数据,为避免一直占据内存空间,需要将其赋为null data[size] = null; size--; //缩容 if(size == data.length/4 && data.length /2 !=0){ resize(data.length/2); } return ret; } //从数组中删除第一个元素 public E removeFirst(){ return remove(0); } //从数组中删除最后一个元素 public E removeLast(){ return remove(size - 1); } //从数组删除某个元素 public void removeElement(E e){ int res = find(e); if(res != -1){ remove(res); } } //获取最后一个元素 public E getLast(){ return get(size-1); } @Override public String toString(){ StringBuilder sb = new StringBuilder(); sb.append(String.format("Array:size = %d,capacity = %d\n",size,data.length)); sb.append("["); for(int i = 0; i < size; i++){ sb.append(data[i]); if(i != size - 1){ sb.append(","); } } sb.append("]"); return sb.toString(); } }
由此我们可以判断:通过索引进行的查找操作时间复杂度为O(1)
addLast()理想情况下为O(1),如果触发扩容则为O(n)。
因此我们在使用ArrayList 集合的时候如果数据量较大而且数据数量已知的时候,
初始化时指定容量大小可以获得较大的性能提升。
下期我们根据封装好的数组实现“ 栈 ” 这种数据结构
---------本文源于日常学习笔记记录,如有错误欢迎批评指正
猜你喜欢
- 2024-09-11 阿里架构师剖析:Redis常用数据类型对应的数据结构
- 2024-09-11 聊聊经典数据结构HashMap,逐行分析每一个关键点
- 2024-09-11 压箱底Redis面试集-48.Redis 的 ListPack 数据结构是什么?
- 2024-09-11 JAVA进阶知识学习-day03 数据结构&List集合&Set集合
- 2024-09-11 Java数据结构面试必问:HashMap 底层实现原理分析
- 2024-09-11 Java路径-31-Java数据结构(我的世界java路径错误怎么办)
- 2024-09-11 《数据结构》第九篇、java中ArrayList源码解析
- 2024-09-11 JDK源码分析--Object(jdk1.8源码详细介绍)
- 2024-09-11 「Java数据结构」Java对象的比较(java对比两个对象属性的变化)
- 2024-09-11 动图+源码,演示Java中常用数据结构执行过程及原理
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)