数据结构---数组

一、基本概念

1. 存放一组相同数据类型的集合

2.在内存中,分配连续的空间,数组创建时要指定大小

3. 定义    数据类型 [] 数组名

//  1.定义一个数组,里面的元素包含10, 20, 24, 17, 35, 58, 45, 74
int arr[] = {10, 20, 24, 17, 35, 58, 45, 74};

4. 获取数组的长度

int length = arr.length;

5.获取数组中指定位置的元素

int number = arr[1];//  第2个位置的值

6.修改数组中指定位置的元素

arr[2] = 100;//  将第三位的数字改为100

7.数组排序

Arrays.sort(arr);

8.遍历数组

for (int i = 0; i < arr.length; i++) {
    System.out.println(arr[i]);
}

9.索引从0开始,最大为数组长度-1

10.访问数组中元素需要通过索引

11.常见的错误:NULLPointException(空指针异常) ArrayIndexOutofBoundsException(数组索引越界)

System.out.println(arr[length]);//  ArrayIndexOutofBoundsException(数组索引越界)

12.常见的数组:字符串,对象数组,哈希表 

二、Java数组的特点

<1>数组在内存中连续分配

<2>创建数组时要指明数组的大小

<3>如何访问数组,通过索引,索引从0开始,到数组的长度-1

<4>使用索引

  • 获取指定索引位置的值 arr[index]

  • 修改指定索引位置的值 arr[index] = 值

  • 删除数组中元素(假删除----空间未被删除)

  • 数组的遍历:将数组中的元素一一打印出来

数组最大的优点:快速查询

三、数组的基本操作 

  1. 构造函数

    public MyArray(int capacity) {
        //  判断容量
        if (capacity < 0) {
            this.capacity = 10;
        } else {
            this.capacity = capacity;
        }
        this.size = 0;
        this.data = (T[]) (new Object[this.capacity]);//  为泛型数组赋值
    }
  2. 获取数组中实际存放元素的个数

    public int getSize() {
        return this.size;
    }
  3. 获取数组的容积 

    public int getCapacity() {
        return this.capacity;
    }
  4. 判断数组是否为空

    public boolean isEmpty() {
        return this.size == 0;
    }
  5. 向数组中添加元素

    public void add(T item) {
        //  this.size  指向的是待插入元素的位置
        addIndex(this.size, item);
    }
    ​
  6. 向数组中添加元素(头部)

    public void addHead(T item) {
        addIndex(0, item);
    }
  7. 根据索引修改值

    public void setValByIndex(int index, T val) {
        //  判断索引范围  不符合抛出异常
        if (index < 0 || index >= this.size) {
            throw new IllegalArgumentException("index is invalid");
        }
        this.data[index] = val;
    }
  8. 扩容resize(自定义扩容函数)

    private void resize(int newCapacity) {
        System.out.println("resize:" + newCapacity);//  打印数组的新容量
        T[] newData = (T[]) (new Object[newCapacity]);//  创建一个新的泛型数组并赋值
        //  将原数组中元素加到新数组
        for (int i = 0; i < this.size; i++) {
        newData[i] = this.data[i];
        }
        //  改变容量与容积
        this.data = Arrays.copyOf(newData, newCapacity);
        this.capacity = newCapacity;
    }
  9. 向数组中在指定位置添加元素

    public void addIndex(int index, T val) {
        //  判断索引范围  不符合抛出异常
        if (index < 0 || index > this.size) {
        throw new IllegalArgumentException("index is invalid");
        }
        //判断数组是否满
        if (this.size == this.capacity) {
        // 扩容   resize  容积扩一倍
        capacity *= 2;
        System.out.println("resize:" + capacity);//  打印数组的新容量
        this.data = Arrays.copyOf(data, capacity * 2);//  使用数组复制函数
        //resize(this.capacity * 2);//  使用自定义函数
        }
        //从index位置开始,元素需要进行后移
        for (int i = this.size - 1; i >= index; i--) {
            this.data[i + 1] = this.data[i];
        }
        //  向指定位置添加元素
        this.data[index] = val;
        //更新this.size
        this.size++;
    }
    ​
  10. 修改指定位置的值

    public void modifyValueByIndex(int index, T value) {
        //  入参判断--对输入的参数进行判断    参数有误抛异常(index is invlid.)
        if (index < 0 || index >= this.capacity) {
            throw new IllegalArgumentException("index is invlid.");
        }
        this.data[index] = value;//  修改指定位置的值
    }
  11. 获取指定索引位置的值

    public T getValueByIndex(int index) {
        //  入参判断--对输入的参数进行判断    参数有误抛异常(index is invlid.)
        if (index < 0 || index >= this.capacity) {
            throw new IllegalArgumentException("index is invlid.");
        }
        return this.data[index];//  返回指定索引的值
    }
    ​
  12. 查询指定的值在数组是否存在

    public int containsValue(T val) { 
        //  遍历数组    返回对应索引  使用比较函数    如存在,获取索引,否则返回-1
        for (int i = 0; i < this.size; i++) {
            if (val.equals(this.data[i])) {
                return i;
            }
        }
        return -1;
    }
  13. 根据索引删除从数组中删除元素

    public T removeByIndex(int index) {
        //  入参判断--对输入的参数进行判断    参数有误抛异常(index is invlid.)
        if (index < 0 || index >= this.size) {
            throw new IllegalArgumentException("index is invlid.");
        }
    ​
        //  删除操作的核心
        /**
         * 1.找到删除的位置
         * 2.删除位置之后的元素要前移   arr[j-1] = arr[j]
         */
        T delValue = this.data[index];//  获取要删除索引的值
        for (int i = index + 1; i < this.size; i++) {
            this.data[i - 1] = this.data[i];
        }
        //  更新数组索引
        this.size--;
        //  判断是否缩容
        if (this.size < this.capacity / 4 && this.capacity / 2 > 0) {
            capacity /= 2;
            this.data = Arrays.copyOf(data, capacity);
            //resize(this.capacity / 2);//  使用自己编写的缩容函数
        }
        return delValue;//  返回删除的值
    }
  14. 重写toString---ctrl+O

    @Override
    public String toString() {
        //  [1,2,3,4,5]
        StringBuilder sb = new StringBuilder("[");
        //  遍历将数据逐个拼接   中间用逗号隔开
        for (int i = 0; i < this.size; i++) {
            sb.append(this.data[i]);
            if (i != this.size - 1) {
                sb.append(",");
            }
        }
        sb.append("]");
        return sb.toString();//  返回字符串
    }
  15. 将一个数组转换为字符串

//  将一个数组转换成字符串
int[] res = {1, 2, 3, 4, 5};
//  方式1
String temp = Arrays.toString(res);
System.out.println(temp);//  [1, 2, 3, 4, 5]
//  方式2
temp = Arrays.stream(res).boxed().map(Objects::toString).collect(Collectors.joining(""));
System.out.printf(temp);//  12345
  1. 向原数组中继续添加一个元素,就会越界(解决办法:扩容)
  2. 只能处理int类型,如何处理多种类型---(解决方法:使用泛型)
  3. 删除元素后,空间利用率低(解决方法:减少容量)

你可能感兴趣的:(数据结构)