前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >java实现自己的ArrayList

java实现自己的ArrayList

作者头像
码农王同学
发布2020-03-25 10:22:01
4770
发布2020-03-25 10:22:01
举报
文章被收录于专栏:后端Coder后端Coder

翻看自己的github觉得将之前写的集合写成一篇文章便于以后自己进行查阅,于此同时也提供给需要的coder,java集合可以说是java程序员必须要掌握的一项基本技术点了,我们每天打交道的就是集合了。

之前写过三篇关于集合源码的文章,需要了解集合源码的可以看下链接。

a.java之CopyOnWriteArraySet源码分析

b.java之CopyOnWriteArrayList源码分析

c.java之ArrayList源码分析

今天要分享的就是关于实现自己的java集合,为以后写基础性文章暂时做下铺垫吧,毕竟现在距离100片篇文章还有一段时间才能编写完。

代码语言:javascript
复制
package com.wpw.springbootmyarraylist;

public interface ISeqList<T> {
    /**
     * 判断集合是否为空
     * @return true/false
     */
    boolean isEmpty();

    /**
     * 获取集合长度
     * @return 集合长度
     */
    int length();

    /**
     * 获取元素
     * @param index 索引
     * @return 指定索引所对应的下标元素值
     */
    T get(int index);

    /**
     * 设置某个元素的值
     * @param index 指定索引
     * @param data 待设置的元素值
     * @return
     */
    T set(int index,T data);

    /**
     * 根据index添加元素
     * @param index 索引index
     * @param data 待添加的元素
     * @return
     */
    boolean add(int index,T data);

    /**
     * 添加元素
     * @param data 待添加的元素信息
     * @return
     */
    boolean  add(T data);

    /**
     * 根据index移除元素
     * @param index 索引index
     * @return
     */
    T remove(int index);

    /**
     * 根据data移除元素
     * @param data 待移除的元素
     * @return
     */
    boolean  remove(T data);

    /**
     * 根据data移除所有元素
     * @param data 待移除的元素
     * @return
     */
    boolean removeAll(T data);

    /**
     * 清空集合
     */
    void clear();

    /**
     * 是否包含data元素
     * @param data 元素data
     * @return
     */
    boolean contains(T data);

    /**
     * 根据值查找下标
     * @param data 元素data
     * @return
     */
    int indexOf(T data);

    /**
     * 根据data查询最后一个出现在顺序表中的下标
     * @param data 元素data
     * @return
     */
    int lastIndexOf(T data);

    /**
     * toString()方法
     * @return 集合内容
     */

    @Override
    String toString();
}

上面定义了集合常用的一些方法的接口,这也是我们用jdk集合最常用的一些方法了。

代码语言:javascript
复制
package com.wpw.springbootmyarraylist;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

public class MyList<T> implements ISeqList<T> {
    /**
     * 数组声明,用于存储元素
     */
    private Object[] table;
    /**
     * 集合大小
     */
    private int length;

    public MyList(int capacity) {
        /***
         * 申请数组存储空间,元素初始化为null
         */
        this.table = new Object[Math.abs(capacity)];
        this.length = 0;
    }

    public MyList() {
        this(64);
    }

    public MyList(T[] array) {
        Objects.requireNonNull(array, "array can not be not empty");
        if (Objects.isNull(array)) {
            throw new NullPointerException("array can not be empty");
        }
        /***
         * 创建对应容量的数组
         */
        this.table = new Object[array.length];
        for (int i = 0; i < array.length; i++) {
            this.table[i] = array[i];
        }
        this.length = array.length;
    }

    @Override
    public boolean isEmpty() {
        return this.length == 0;
    }

    @Override
    public int length() {
        return this.length;
    }

    @Override
    public T get(int index) {
        if (index >= 0 && index < this.length) {
            return (T) table[index];
        }
        return null;
    }

    @Override
    public T set(int index, T data) {
        if (index >= 0 && index < this.length && data != null) {
            T old = (T) this.table[index];
            this.table[index] = data;
            return old;
        }
        return null;
    }

    @Override
    public boolean add(int index, T data) {
        if (Objects.isNull(data)) {
            return false;
        }
        /***
         * 插入下标的容错判断,插入在最前面
         */
        if (index < 0) {
            index = 0;
        }
        /**
         * 插入下标的容错判断,插入在最后面
         */
        if (index > this.length) {
            index = this.length;
        }
        /***
         * 判断内部数组是否已满
         */
        if (this.length == table.length) {
            Object[] temp = this.table;
            /***
             * 把原数组赋值给临时数组
             */
            /***
             * 对原数组进行成倍扩容,并把原数组的元素赋值到新数组
             */
            this.table = new Object[temp.length << 1];
            /***
             * 先把原数组下标从0到index-1(即插入位置的前一个位置复制到新数组
             */
            for (int i = 0; i < index; i++) {
                this.table[i] = temp[i];
            }
        }
        /***
         * 从原数组的最后一个元素开始直到index,都往后一个位置
         * 最后腾出来的位置就是新插入元素的位置了
         */
        for (int j = this.length - 1; j >= index; j--) {
            this.table[j + 1] = this.table[j];
        }
        /***
         * 插入新值
         */
        this.table[index] = data;
        /***
         * 长度加一
         */
        this.length++;
        /**
         * 插入成功
         */
        return true;
    }

    @Override
    public boolean add(T data) {
        return add(this.length, data);
    }

    @Override
    public T remove(int index) {
        if (this.length != 0 && index >= 0 && index < this.length) {
            /**
             * 记录删除元素的值并返回
             */
            T old = (T) this.table[index];
            /**
             * 从被删除的元素开始,其后的元素都一次往前移动
             */
            for (int j = index; j < this.length - 1; j++) {
                this.table[j] = this.table[j + 1];
            }
            /***
             * 设置数组元素对象为空
             */
            //gc
            this.table[this.length - 1] = null;
            /***
             * 顺序表长度减一
             */
            this.length--;
            return old;
        }
        return null;
    }

    @Override
    public boolean remove(T data) {
        if (this.length != 0 && data != null) {
            return this.remove(this.indexOf(data)) != null;
        }
        return false;
    }

    @Override
    public boolean removeAll(T data) {
        boolean done = false;
        if (this.length != 0 && data != null) {
            int i = 0;
            while (i < this.length) {
                if (data.equals(this.table[i])) {
                    this.remove(i);
                    done = true;
                } else {
                    i++;
                }
            }
        }
        return done;
    }

    @Override
    public void clear() {
        this.length = 0;
        for (int i = 0; i < this.length; i++) {
            //gc
            this.table[i] = null;
        }
    }

    @Override
    public boolean contains(T data) {
        return this.indexOf(data) >= 0;
    }

    @Override
    public int indexOf(T data) {
        if (data != null) {
            for (int i = 0; i < this.length; i++) {
                /**
                 * 相等则返回下标
                 */
                if (this.table[i].equals(data)) {
                    return i;
                }
            }
        }
        return -1;
    }

    @Override
    public int lastIndexOf(T data) {
        if (data != null) {
            for (int i = this.length - 1; i >= 0; i--) {
                if (data.equals(this.table[i])) {
                    return i;
                }
            }
        }
        return -1;
    }

    @Override
    public String toString() {
        List<String> list=new ArrayList<>();
        StringBuilder stringBuilder = new StringBuilder("(");
        if (this.length != 0) {
            for (int i = 0; i < this.length-1; i++) {
                stringBuilder.append(this.table[i].toString() + ",");
            }
            stringBuilder.append(this.table[this.length - 1].toString());
        }
        return stringBuilder.append(")").toString();
    }
}

由于上面的注释说明很清晰了,可以进行测试了。

代码语言:javascript
复制
package com.wpw.springbootmyarraylist;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class Test {
    public static void main(String[] args) {
        ISeqList myArrayList=new MyList();
        myArrayList.add("1");
        myArrayList.add("2");
        myArrayList.add("3");
        log.info("打印集合的元素信息:{}",myArrayList.toString());
        log.info("判断集合是否为空:{}",myArrayList.isEmpty());
        log.info("集合大小:{}",myArrayList.length());
        log.info("集合包含元素1:{}",myArrayList.contains("1"));
        log.info("集合元素1的索引位置:{}",myArrayList.indexOf("1"));
        log.info("集合元素2的索引位置:{}",myArrayList.indexOf("2"));
        log.info("获取集合索引下标为0的元素:{}",myArrayList.get(0));
        log.info("删除集合中某个索引下标位置的元素");
        myArrayList.remove(2);
        log.info("此时集合元素大小:{}",myArrayList.length());
        log.info("获取集合元素的索引下标:{}",myArrayList.lastIndexOf("2"));
        log.info("打印集合的元素信息:{}",myArrayList.toString());
    }
}

整个自定义集合的实现就结束了,喜欢文章的可以关注转发。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-01-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 码农王同学 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档