数据结构-数组

导读:本篇文章讲解 数据结构-数组,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

数据结构-数组

Java数组

在Java中,数组是用来存储一组数据类型相同的元素,如整数(int),浮点数(double,float),引用类型(java类库中的类,自定义类的实例化对象)

定义

  • 数据类型[] 数组名

  • 数据类型 数组名[] (不推荐)

初始化

  • 数据类型[] 数组名 = new 数据类型[size]
  • 数据类型[] 数组名 = {元素1,元素2…}

索引

  • 数组中通过索引(从0开始)来实现对数组元素的增删改查

数组优点

  • 由于数组在内存中分配连续空间,适合快速查询

自定义数组

基于java中的数组,进行二次封装,制作自己的数组(容量可变的数组),并使其具有增删改查的功能

先创建自定义数组类(使用泛型–只能存储类的对象,ps:基本数据类型用包装类)

public class MyselfArray<T> {

	//数组当前元素个数
    private int size;

    //泛型数组
    private T[] data;
    
    //构造方法
    
    //数组其他方法
}

构造

添加构造方法

	/**
     * 默认无参构造容量为10的数组
     */
    public MyselfArray() {
        //调用有参构造方法
        this(10);
    }

    /**
     * 有参构造方法
     * @param capacity 数组可存储的容量
     */
    public MyselfArray(int capacity) {
        this.size = 0;
        data = (T[]) new Object[capacity];//强制类型转换
    }

其他方法

	/**
     * 返回元素个数
     * @return int
     */
    public int getSize() {
        return this.size;
    }

    /**
     * 返回数组容量
     * @return int
     */
    public int getCapacity() {
        return data.length;
    }

	/**
     * 判断数组是否为空
     * @return boolean
     */
    public boolean isEmpty() {
        return this.size == 0;
    }

	/**
     * 是否包含指定的元素
     * @param elem 目标元素
     * @return int
     */
    public int isContains(T elem) {
        for (int i = 0; i < size; i++) {
            //包含返回目标元素索引
            if (data[i].equals(elem)) {
                return i;
            }
        }
        //不包含返回-1
        return -1;
    }

	/**
     * 重写toString()方法
     * @return String
     */
    @Override
    public String toString() {
        StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append("[");

        for (int i = 0; i < this.size; i++) {
            stringBuffer.append(data[i]);
            //每个元素用","隔开
            if (i != this.size - 1) {
                stringBuffer.append(",");
            }
        }

        stringBuffer.append("]");
        return stringBuffer.toString();
    }

修改容量

Java中数组的容量是固定的,所以我们并不是修改数组本身,而是创建新的数组,将元素复制到新数组

	/**
     * 重新设置容量大小,进行扩容/缩容
     * @param newCapacity 新数组容量数组
     */
    public void resize(int newCapacity) {
        //创建新数组
        T[] newData = (T[]) new Object[newCapacity];
        //复制元素
        for (int i = 0; i < this.size; i++) {
            newData[i] = data[i];
        }
        //复制数组
        this.data = newData;
    }

向数组指定位置添加元素

    public void add(int index, T elem) {
        //目标索引必须处在0~size之间
        if (index < 0 || index > this.size) {
            throw new IllegalArgumentException("index is error");
        }

        //当数组容量已满时,进行扩容操作(2倍)
        if (this.size == data.length) {
            resize(2 * data.length);
        }
        
        /*
        将要插入的元素后方向后移
        1.从后向前遍历,找到插入位置(0~size)
        2.将插入位置之后的所有元素全部向后移一位
        3.插入一个元素后,size+1
        */
        //          末尾元素   到要插入的下标停止遍历
        for (int i = this.size - 1; i >= index; i--) {
            //将目标索引及之后的元素向后移
            data[i + 1] = data[i];
        }
        //将目标元素添加到目标位置
        data[index] = elem;
        //添加元素后,有效元素数+1
        this.size++;
        //释放空间
        //data[size]=null;
    }

向数组末尾添加元素(调用add()方法)

	/**
     * 向末尾添加元素
     */
    public void addLast(T elem) {
        //尾部待插入元素索引为size
        //index : 0 1 2 3 4 5 
        //size  : 1 2 3 4 5 null  
        add(this.size, elem);
    }

向数组头部添加元素(调用add()方法)

	public void addFirst(T elem) {
        //头部索引为0
        add(0, elem);
    }

删除指定位置元素

	/**
     * 删除指定位置的元素
     * @param index 目标索引
     * @return 目标索引的值
     */
    public T remove(int index) {
        //目标索引必须处在0~size-1之间
        if (index < 0 || index >= this.size) {
            throw new IllegalArgumentException("index is invalid");
        }

        //当有效元素数<=数组容量的1/4时    缩容 为 1/2
        if (this.size <= (data.length / 4) && data.length / 2 > 0) {
            resize(data.length / 2);
        }

        //记录将被删除的元素
        T result = data[index];

        /*
            将要插入的元素后方向后移
            1.从前向后遍历,找到删除位置(0~size-1)
            2.记录待删除位置的元素
            2.将删除位置之后的所有元素全部向前移一位
            3.删除一个元素后,size-1
         */

        //将目标索引之后的索引对应元素向前移一位
        for (int i = index + 1; i < this.size; i++) {
            data[i - 1] = data[i];
        }

        this.size--;
        data[size] = null;

        //返回被删除的元素
        return result;

    }

删除头部元素–调用remove()

	/**
     * 删除第一个元素
     */
    public T removeFirst() {
        return remove(0);
    }

删除尾部元素–调用remove()

	/**
     * 删除末尾元素
     */	
	public T removeLast() {
        return remove(this.size - 1);
    }

删除指定元素

	public int removeElem(T elem) {
        //查询目标元素的索引,-1表示不存在该元素
        int index = this.isContains(elem);

        if (index == -1) {
            return -1;
        } else {
            remove(index);
        }

        return index;
    }

修改指定位置的值

	/**
     * 修改指定位置的元素
     * @param index
     * @param elem
     */
    public void replace(int index, T elem) {
        //当索引不在有效元素范围内(0~size-1)时
        if (index < 0 || index >= this.size) {
            throw new ArrayIndexOutOfBoundsException("index is error");
        }
		//将旧元素替换为目标元素
        data[index] = elem;
    }

替换元素(新元素代替旧元素)

	/**
     * 替换元素
     * @param elem  指定元素
     * @param newElem 替换元素
     */
    public int replace(T elem, T newElem) {

        int index = this.isContains(elem);

        if(index==-1){
            return -1;
        }else {
            data[index] = newElem;
        }
        return index;
    }

返回指定位置的元素

	/**
     * 返回指定位置的元素
     * @param index 返回数组元素的索引
     * @return int
     */
    public T getElemByIndex(int index) {
        //当索引不在有效元素范围内(0~size-1)时
        if (index < 0 || index >= this.size) {
            throw new ArrayIndexOutOfBoundsException("index is error");
        }

        return data[index];
    }

返回指定元素的索引

	/**
     * 返回指定元素的索引  元素可能重复,只能返回遇到的第一个元素
     * @param elem 指定元素
     * @return int 非-1为元素索引,-1表示不存在此元素
     */
    public int getIndexByElem(T elem){
        return this.isContains(elem);
    }

测试数组的方法

package com.company.project.subject.day1;

public class Test {

    public static void main(String[] args) {

        MyselfArray<Integer> array = new MyselfArray<>();

        for (int i = 0; i < 5; i++) {
            array.addLast(i+3);
        }
        System.out.println("====增====");
        System.out.println("末尾添加:"+array);
        array.addFirst(1);
        System.out.println("头部添加:"+array);
        array.add(1, 2);
        System.out.println("指定位置添加:"+array);

        System.out.println("====查====");
        System.out.println("查询指定索引的元素:"+array.getElemByIndex(5));
        System.out.println("查询指定元素的索引:"+array.getIndexByElem(5));

        System.out.println("====改====");
        array.replace(6, Integer.valueOf(8));
        System.out.println("修改指定位置的元素:"+array);
        array.replace(Integer.valueOf(8), Integer.valueOf(7));
        System.out.println("替换指定元素:"+array);

        System.out.println("====删====");
        array.remove(2);
        System.out.println("删除指定位置元素:"+array);
        array.removeFirst();
        System.out.println("删除头部元素:"+array);
        array.removeLast();
        System.out.println("删除尾部元素:"+array);

    }
}

运行结果:

在这里插入图片描述

自定义数组类完整代码

package com.company.project.subject.day1;

/**
 * 数组
 */
public class MyselfArray<T> {

    //数组当前元素个数
    private int size;

    //数组
    private T[] data;

    /**
     * 默认无参构造容量为10的数组
     */
    public MyselfArray() {
        //调用有参构造方法
        this(10);
    }

    /**
     * 有参构造方法
     * @param capacity 数组可存的容量
     */
    public MyselfArray(int capacity) {
        this.size = 0;
        data = (T[]) new Object[capacity];//强制类型转换
    }

    /**
     * 向指定位置添加元素
     * @param index 索引
     */
    public void add(int index, T elem) {
        //目标索引必须处在0~size之间
        if (index < 0 || index > this.size) {
            throw new IllegalArgumentException("index is error");
        }

        //当数组容量已满时,进行扩容操作(2倍)
        if (this.size == data.length) {
            resize(2 * data.length);
        }

        /*
            将要插入的元素后方向后移
            1.从后向前遍历,找到插入位置(0~size)
            2.将插入位置之后的所有元素全部向后移一位
            3.插入一个元素后,size+1
         */
        //          末尾元素   到要插入的下标停止遍历
        for (int i = this.size - 1; i >= index; i--) {
            //将目标索引及之后的元素向后移
            data[i + 1] = data[i];
        }
        //将目标元素添加到目标位置
        data[index] = elem;
        //添加元素后,有效元素数+1
        this.size++;
        //释放空间
        //data[size]=null;

    }

    /**
     * 向头部添加元素
     */
    public void addFirst(T elem) {
        //头部索引为0
        add(0, elem);
    }

    /**
     * 向末尾添加元素
     */
    public void addLast(T elem) {
        //尾部待插入元素索引为size
        //index : 0 1 2 3 4 5
        //size  : 1 2 3 4 5 null
        add(this.size, elem);
    }

    /**
     * 重新设置容量大小,进行扩容/缩容
     *
     * @param newCapacity 新数组容量
     */
    private void resize(int newCapacity) {
        //创建新数组
        T[] newData = (T[]) new Object[newCapacity];
        //复制元素
        for (int i = 0; i < this.size; i++) {
            newData[i] = data[i];
        }
        //复制数组
        this.data = newData;
    }

    /**
     * 删除指定位置的元素
     *
     * @param index 目标索引
     * @return 目标索引的值
     */
    public T remove(int index) {
        //目标索引必须处在0~size-1之间
        if (index < 0 || index >= this.size) {
            throw new IllegalArgumentException("index is invalid");
        }

        //当有效元素数<=数组容量的1/4时    缩容 为 1/2
        if (this.size <= (data.length / 4) && data.length / 2 > 0) {
            resize(data.length / 2);
        }

        //记录将被删除的元素
        T result = data[index];

        /*
            将要插入的元素后方向后移
            1.从前向后遍历,找到删除位置(0~size-1)
            2.记录待删除位置的元素
            2.将删除位置之后的所有元素全部向前移一位
            3.删除一个元素后,size-1
         */

        //将目标索引之后的索引对应元素向前移一位
        for (int i = index + 1; i < this.size; i++) {
            data[i - 1] = data[i];
        }

        this.size--;
        data[size] = null;

        //返回被删除的元素
        return result;

    }

    /**
     * 删除指定的元素
     * (若有重复元素  只能删除第一次找到的元素)
     *
     * @param elem 目标元素
     * @return 目标元素的索引
     */
    public int removeElem(T elem) {
        int index = this.isContains(elem);

        if (index == -1) {
            return -1;
        } else {
            remove(index);
        }

        return index;
    }

    /**
     * 删除第一个元素
     */
    public T removeFirst() {
        return remove(0);
    }

    /**
     * 删除末尾元素
     */
    public T removeLast() {
        return remove(this.size - 1);
    }


    /**
     * 返回指定位置的元素
     * @param index 返回数组元素的索引
     * @return int
     */
    public T getElemByIndex(int index) {
        //当索引不在有效元素范围内(0~size-1)时
        if (index < 0 || index >= this.size) {
            throw new ArrayIndexOutOfBoundsException("index is error");
        }

        return data[index];
    }

    /**
     * 返回指定元素的索引  元素可能重复,只能返回遇到的第一个元素
     * @param elem 指定元素
     * @return int
     */
    public int getIndexByElem(T elem){
        return this.isContains(elem);
    }

    /**
     * 修改指定位置的元素
     * @param index 指定位置
     * @param elem  替换元素
     */
    public void replace(int index, T elem) {
        //当索引不在有效元素范围内(0~size-1)时
        if (index < 0 || index >= this.size) {
            throw new ArrayIndexOutOfBoundsException("index is error");
        }

        //将旧元素替换为目标元素
        data[index] = elem;
    }

    /**
     * 替换元素
     * @param elem  指定元素
     * @param newElem 替换元素
     */
    public int replace(T elem, T newElem) {

        int index = this.isContains(elem);

        if(index==-1){
            return -1;
        }else {
            data[index] = newElem;
        }
        return index;
    }

    /**
     * 判断数组是否为空
     *
     * @return boolean
     */
    public boolean isEmpty() {
        return this.size == 0;
    }


    /**
     * 是否包含指定的元素
     *
     * @param elem 目标元素
     * @return int
     */
    public int isContains(T elem) {
        for (int i = 0; i < size; i++) {
            //包含返回目标元素索引
            if (data[i].equals(elem)) {
                return i;
            }
        }

        //不包含返回-1
        return -1;
    }

    /**
     * 重写toString
     *
     * @return String
     */
    @Override
    public String toString() {
        StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append("[");

        for (int i = 0; i < this.size; i++) {
            stringBuffer.append(data[i]);
            //每个元素用","隔开
            if (i != this.size - 1) {
                stringBuffer.append(",");
            }
        }

        stringBuffer.append("]");
        return stringBuffer.toString();
    }

    /**
     * 返回元素个数
     *
     * @return int
     */
    public int getSize() {
        return this.size;
    }

    /**
     * 返回数组容量
     *
     * @return int
     */
    public int getCapacity() {
        return data.length;
    }

}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/15633.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!