栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java顺序表模拟实现

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java顺序表模拟实现

        ArrayList是java的一种集合类,它的底层是一个可变数组,可以存放任何Object的协变类型的引用,即java中的所有对象。通过模拟实现ArrayList集合类,可以帮助我们了解其底层实现原理,以及简单泛型的使用。

        在MyArrayList类中有一个泛型数组,用于存放元素,以及最大容量capacity和目前存放元素的数量size,目的是为了方便统计,以及后面的扩容操作。给该类提供了一个无参的构造方法(默认初始容量为10),和带参构造方法(指定初始容量)。需要注意的是data为泛型数组,然而泛型数组不能直接new,我们暂且只能先创建一个Object类型的数组然后将其强制类型转换为泛型数组。

public class MyArrayList {
    private int capacity;//最大容量
    private T[] data;
    private  int size;//目前存储元素的数量

    public MyArrayList(){
        this.capacity=10;
        this.data=(T[])new Object[capacity];
    }

    public MyArrayList(int capacity) {
        this.capacity = capacity;
        this.data=(T[])new Object[capacity];
    }

        然后我们为其提供添加元素的方法。使用者可以默认直接添加一个元素在数组末端,或者是将一个元素添加到指定位置,此时就需要将后面的元素依次往后移一位。需要注意的是添加元素前需要先检查顺序表是否已满,如果已装满则需要先扩容。当使用者指定下标时,需要先校验下标是否合法,不合法时需要处理。每当使用者添加一个元素后,size需要加一。

        

    public void add(T element){
        //在当前顺序表的末端添加一个元素
        if(isFull()){
            dilatation();//扩容方法
        }
        this.data[this.size]=element;
        this.size++;
    }

    public void add(int index,T element){
        //在指定下标位置添加元素,需校验指定下标的合法性
        if(isFull()){
            dilatation();
        }
        if(index>this.size){
            System.out.println("数组下标越界!");
            return;
        }
        for(int i=this.size;i>index;i--){
            this.data[i]=data[i-1];
        }
        this.data[index]=element;
        this.size++;
    }

        下来我们实现扩容方法。扩容方法只有在顺序表已满的情况下才会被add方法调用,这个方法无须使用者调用,我们用private封装起来。 数组扩容的原理:我们先创建一个大容量的数组,然后将原来的数组内容拷贝到新的数组中,然后将顺序表对象中的数组引用指向新的数组。这部分有一个问题需要特别注意,顺序表扩容后的容量默认为原来的1.5倍,但如果原顺序表的容量为1,由于capacity为int类型的,计算扩容后的容量结果依旧为1,此时如果add直接添加新元素将会出现数组下标越界的异常。我们可以为其甚至一个默认最小扩容单位,让扩容·的大小不小于这个值。这个值也不能小于add每次添加的最少元素数量。

    private boolean isFull(){
        if(this.size==this.capacity){
            return true;
        }
        return false;
    }

    private void dilatation(){
        int min=5;
        if(min>this.capacity>>1){
            this.capacity=this.capacity+min;
        }else{
            this.capacity=this.capacity+this.capacity>>1;
        }
        this.data= Arrays.copyOf(this.data,this.capacity);
    }

        接下来我们为顺序表提供删除元素的方法。这里可对比添加元素的方法,将需要删除的位置用其后方的元素覆盖即可,然后依次覆盖,将最后一个元素置为null,size减一。清空顺序表还可以直接将data置为null,至于原来的那块空间未被引用就会被jvm回收。

public void remove(int index){
        //删除指定下标位置的元素
        if(index>this.size-1){
            System.out.println("数组下标越界!");
            return;
        }
        for(int i=index;i 

        查找和改写元素的方法较为简单,按照下标查找的话需要返回泛型类的元素。

    public int search(T element){
        //在顺序表中搜索element元素,若能找到则返回找到的第一个相同元素的下标
        //若不能找到则返回-1
        for (int index=0;indexthis.size-1){
            System.out.println("数组下标越界!");
            return null;
        }
        return this.data[index];
    }

    public void set(int index,T element){
        //将指定下标的元素修改为指定元素
        if(index>this.size-1){
            System.out.println("数组下标越界!");
            return;
        }
        this.data[index]=element;
    }

    public int length(){
        return this.size;
    }

    public void print(){
        for(int i=0;i 

        为方便测试,我们为其编写了length方法和print打印方法。测试中,当我们往顺序表中放基本数据类型的话,需要装箱,所以我们为其提供的泛型类型应该为它们的包装类。

public class Main{
    public static void main(String[] args) {
        MyArrayList array = new MyArrayList<>(1);
        array.add(1);
        array.add(2);
        array.add(3);
        array.add(4);
        array.add(4, 5);
        array.print();
        array.remove(0);
        array.print();
    }
}

 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/768259.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号