第三次总结

  1. 数组的特点?
  2. 数组如果要存储的数据个数不确定,怎么办??
  3. 自定义的性能差在什么地方??
  4. 扩容方案:为什么是扩容到原来的1.5倍,为什么要这样??
  5. 什么是栈?什么是队列

 


 

一、数组的特点?

 

  1. 一旦定义,长度不可变
  2. 可以通过下标访问
  3. 数据类型确定
  4. 数据类型是object 的子类
  5. 元素的内存地址是连续的
  6. 地址连续的目的是为了提高访问效率,可以快速通过下标定位到某一个元素

 

 

二、数组如果要存储的数据个数不确定,怎么办??

 

  可扩容的数组,长度可变的数组
  在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.每次都需要将数据从原数组拷贝到新数组,需要耗费时间

解决方案

  1. 能否减少创建数组的次数
  2. 减少数组元素的拷贝次数
  3. 定义初始数组的时候,给定的数组可以有初始容量
  4. 在数组装满之前,不再创建新的数组
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
先进先出

 

posted @ 2020-07-16 18:49  Zc小白  阅读(130)  评论(0)    收藏  举报