第三次总结
- 数组的特点?
- 数组如果要存储的数据个数不确定,怎么办??
- 自定义的性能差在什么地方??
- 扩容方案:为什么是扩容到原来的1.5倍,为什么要这样??
- 什么是栈?什么是队列
一、数组的特点?
- 一旦定义,长度不可变
- 可以通过下标访问
- 数据类型确定
- 数据类型是object 的子类
- 元素的内存地址是连续的
- 地址连续的目的是为了提高访问效率,可以快速通过下标定位到某一个元素
二、数组如果要存储的数据个数不确定,怎么办??
可扩容的数组,长度可变的数组
在Java中已经实现了长度可变的数组,ArrayList和Vector
三、自定义的性能差在什么地方??
定义一个MyList方法
public class MyList { //定义一个长度是0的初始数组,用来存放元素 //初始状态还没有存放任何元素,所以数组长度是0 //每增加一个元素,数组长度要改变一次 private String[] src = new String[0]; public void add(String s) { //定义一个新的数组,长度是src的长度+! String[] dest = new String[src.length + 1]; /* //将src中的元素拷贝到dest中 for (int i = 0; i < src.length; i++) { dest[i] = src[i]; } //将src指向dest src = dest;*/ //src = Arrays.copyOf(src, src.length + 1); System.arraycopy(src, 0, dest, 0, src.length); //将新元素防盗src的最后一个下表位置 src = dest; src[src.length - 1] = s; } //根据索引删除元素 //index 要修改的元素的索引 public void remove(int index) { int count = 0; String[] dest = new String[src.length - 1]; for (int i = 0; i < src.length; i++) { if (i != index) { dest[count] = src[i]; count++; } } src = dest; } //修改制定索引位置的元素 //index 要修改的元素的索引 //newStr 要修改的元素 public void modify(int index, String newStr) { src[index] = newStr; } //获得指定索引位置的元素 //index 要修改的元素的索引 public String get(int index) { return src[index]; } //返回容器的长度(容器中元素的个数) public int size() { return src.length; } public void insert(int index, String newStr) { String[] dest = new String[src.length + 1]; System.arraycopy(src, 0, dest, 0, index); System.arraycopy(src, index, dest, index + 1, src.length - index); src = dest; src[index]=newStr; } }
定义一个测试类MyListTest
public class MyListTest { public static void main(String[] args) { //创建一个容器的对象 MyList list =new MyList(); //增加数据 list.add("张三"); list.add("李四"); list.add("王五"); list.add("赵六"); list.add("田七"); list.modify(0,"小明"); list.insert(4,"小红"); for(int i=0;i<list.size();i++){ String s =list.get(i); System.out.println(s); } } }
和java自带的方法比较
1.每次增加数据,都创建了一个新数组,开辟内存需要等待时间
2.每次都需要将数据从原数组拷贝到新数组,需要耗费时间
解决方案
- 能否减少创建数组的次数
- 减少数组元素的拷贝次数
- 定义初始数组的时候,给定的数组可以有初始容量
- 在数组装满之前,不再创建新的数组
public class MyList { //定义初始大小为10的数组 String[] src = new String[10]; //count为当前数组中元素的个数 private int count = 0; public void add(String s) { if (count == src.length) { //位运算,每次增加数组长度的1.5倍
//位运算要用括号括起,与加减同级 String[] dest = new String[src.length + (src.length >> 1)]; System.arraycopy(src, 0, dest, 0, count); src = dest; } src[count] = s; count++; }
四、扩容方案:为什么是扩容到原来的1.5倍,为什么要这样?
时间复杂度
空间复杂度
容量越少,扩容个数就越少,本来数组长度就小,每次扩容耗费的时间相对较短
容量越多,扩容个数越多,这个时候,要么就不扩容,要扩就一次多扩一点,减少扩容次数
如果每次扩容的太少,就意味着要增加扩容次数
如果每次扩容的太多,就意味着要增加扩容的时间
为什么不是1.4倍?1.6倍
1.5倍刚好均衡,并且可以使用位移运算
五、什么是栈?什么是队列
栈 [Stack]
以 LIFO 方式进行数据操作的一种数据结构
LIFO: Last In First Out
后进先出,最后放进来的数据最先被取出
队列[Queue]
以 FIFO 方式进行数据操作的一种数据结构
FIFO: First In First Out
先进先出

浙公网安备 33010602011771号