Java实现:数组实现可扩容线性表

本文展示了如何使用Java实现一个基于数组的可扩容线性表`MyArrayList`。类包括了添加、删除、查找和插入等基本操作,并通过动态扩容确保线性表的容量。代码详细注释解释了每个方法的功能和实现逻辑。
摘要由CSDN通过智能技术生成
/*
数组实现可扩容线性表
 */
class MyArrayListTest {
    public static void main(String[] args) {
        MyArrayList<String> arrayList = new MyArrayList<>(3);
        arrayList.add("a");
        arrayList.add("b");
        arrayList.add("c");
        arrayList.add("d");
//        System.out.println(arrayList.contains("a"));
//        arrayList.remove("d");
//        arrayList.insert(0 ,"e");
        arrayList.remove(0);
        System.out.println(arrayList);
    }
}

//数组线性表类
public class MyArrayList<T> {
    //底层数组
    Object[] arr;
    //元素数量
    int size;
    //数组定义的最大长度
    static final int MAX_CAPACITY = Integer.MAX_VALUE - 8;

    public MyArrayList() {
        //默认构造长度10
        this.arr = new Object[10];
    }

    public MyArrayList(int initCapacity) {
        if (initCapacity < 1 || initCapacity > MAX_CAPACITY) throw new IllegalArgumentException("param is illegal");
        this.arr = new Object[initCapacity];
    }

    /**
     * 判断表是否为空
     *
     * @return true 空
     */
    public boolean isEmpty() {
        return size == 0;
    }

    /**
     * 往线性表中尾部添加元素的方法
     *
     * @param t 要添加的元素
     * @return true 成功
     */
    public boolean add(T t) {
        //添加的元素不能为空
        if (t == null) throw new IllegalArgumentException("param is null");
        //如果数组满了,扩容得到新数组
        if (size == arr.length) {
            int newLen = getLen();
            grow(newLen);
        }
        //到这里说明底层数组扩容成功
        arr[size++] = t;
        return true;
    }

    /**
     * 判断表中是否包含某一元素,并返回元素下标
     * @param t
     * @return 返回下标,-1代表元素不存在
     */
    public int contains(T t) {
        //查询的元素不能为null
        if (t == null) throw new IllegalArgumentException("param is null");
        int tag = -1;
        //表为空,直接返回-1
        if (isEmpty()) return tag;
        //遍历,找到了就返回对应元素的下标
        for (int i = 0; i < size; i++) {
            if (arr[i].equals(t)) {
                tag = i;
                break;
            }
        }
        return tag;
    }

    /**
     * 删除表中某一个元素
     *
     * @param t 要删除的元素
     * @return true 删除成功
     */
    public boolean remove(T t) {
        //删除的元素不能为null
        if (t == null) throw new IllegalArgumentException("param is null");
        //表为空,抛出异常
        if (isEmpty()) throw new RuntimeException("List is empty");
        //遍历查找元素/可以用contains方法
        int tag = -1;
        for (int i = 0; i < size; i++) {
            if (arr[i].equals(t)) {
                tag = i;
                break;
            }
        }
        //没找到元素,返回false
        if (tag == -1) return false;
        //从要删除的元素处开始遍历,将后面所有的数据往前挪一位,最后一位数据不用考虑再赋值
        for (int i = tag; i < size - 1; i++) {
            arr[i] = arr[i + 1];
        }
        //元素长度减1
        size--;
        return true;
    }
    /**
     * 根据数组下标插入元素的方法
     *
     * @param index 要插入元素的下标
     * @param t 要插入的元素
     * @return true 插入成功
     */
    public boolean insert(int index,T t) {
        //插入元素的下标只能是[0,size]
        if(index<0||index>size) throw new IllegalArgumentException("param is illegal");
        //如果是从数组尾部插入元素,调用前面的方法
        if(index == size){
            add(t);
            return true;
        }
        //如果当前数组元素已经满了,先扩容
        if(size == arr.length){
            int newLen = getLen();
            grow(newLen);
        }
        //进行插入操作,先将目标下标元素及其后面元素后移,再赋值,从后往前操作
        for (int i = size;i>index; i--){
            arr[i] = arr[i-1];
        }
        arr[index] = t;
        size++;
        return true;
    }
    /**
     *根据指定下标删除元素
     * @param index
     * @return
     */
    public T remove(int index){
        //插入元素的下标只能是[0,size)
        if(index<0||index>size-1) throw new IllegalArgumentException("param is illegal");
        //将对应下标的元素的后面元素全部前移,最后一个元素不用操作
        T value = (T)arr[index];
        for (int i = index;i<size-1;i++){
            arr[i]=arr[i+1];
        }
        size--;
        return value;
    }
    /**
     * 数组扩容的私有方法
     *
     * @param newLen :扩容后数组的长度
     */
    private void grow(int newLen) {
        //创建新数组
        Object[] objects = new Object[newLen];
        //转移原来数组的元素到新数组上
        for (int i = 0; i < arr.length; i++) {
            objects[i] = arr[i];
        }
        //让新数组成为当前底层数组
        arr = objects;
    }

    /**
     * 获取扩容数组长度的私有方法
     *
     * @return 新数组的长度
     */
    private int getLen() {
        int oldLen = arr.length;
        //如果扩容前数组长度已经为最大值,抛出异常
        if (oldLen == MAX_CAPACITY) throw new RuntimeException("Arr is fullMax");
        //新数组扩容后的长度等于原来数组长度的两倍
        int newLen = (oldLen << 1);
        //如果扩容后长度参数溢出或者大于最大数组长度,就让数组扩容为最大长度
        if (newLen < 0 || newLen > MAX_CAPACITY) {
            newLen = MAX_CAPACITY;
        }
        return newLen;
    }

    @Override
    public String toString() {
        //打印线性表时只打印有效元素,如:[],[a,b,c]
        if (size == 0) return "[]";
        StringBuilder s = new StringBuilder();
        s.append("[");
        for (int i = 0; i < size; i++) {
            s.append(arr[i] + ",");
        }
        //去掉最后的逗号
        String str = s.toString().substring(0, s.length() - 1);
        return str + "]";
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值