java 封装数组 手写ArrayList

直接对数组操作时,会遇到以下问题。

1.当需要添加元素时,元素已经满了的情况需要对数组进行扩容。

2.删除数组中某个元素时,需要移动该元素以后的元素位置。

3.没有一些常用的方法,比如说数组中是否包含某个元素,数组是否为空等。

4.其他问题

于是对数组中的各种操作进行封装,方便调用。java中已经实现了这样的工具类ArrayList,但是我们不知道它是如何实现的,那么现在我们就来重写以下这个工具类吧。(后面有些不常用的方法未进行重写,sorry)

package com.zzb.utils;

import java.io.Serializable;
import java.util.*;

/**
 * Created by zzb on 2019/1/31.
 * @Author zzb
 * @Description 模拟arrayList的实现
 *
 */
public class ArrayUtils<T> extends AbstractList<T>
        implements List<T> {
    //数组长度
    private int size;
    //数组容量
    private int capacity = 10;
    //数组扩容系数
    private static final double resizeCoefficient = 1F;
    //声明的数组为一个全局变量
    transient   Object[] arr ;
    //默认容量为空的数组
    private static final Object[] DEFAULT_CAPACITY_EMPTY = {};

    /**
     * 重写构造函数,初始化数组
     */
    public ArrayUtils(int initialCapacity){
        if (initialCapacity > 0) {
            this.arr = new Object[initialCapacity];
        } else if (initialCapacity == 0) {
            this.arr = DEFAULT_CAPACITY_EMPTY;
        } else {
            throw new IllegalArgumentException("Illegal Capacity: "+
                    initialCapacity);
        }
    }
    public ArrayUtils(){//无参构造函数,默认容量为10
        this.arr = DEFAULT_CAPACITY_EMPTY;
    }
    /**
     * 获得数组长度
     * @return 数组长度
     */
    @Override
    public int size() {
        return size;
    }
    /**
     * 数组下标越界检查
     */
    private void rangeCheck(int index) {
        if (index >= size)
            throw new IndexOutOfBoundsException("数组下标越界,越界下标:"+index);
    }

    /**
     * 判断数组是否为空数组
     * @return
     */
    @Override
    public boolean isEmpty() {
        //官方写法就一句话 :return size == 0;
        if(size==0){
            return true;
        }
        return false;
    }

    /**
     * 数组中是否包含元素o
     * @param o
     * @return
     */
    @Override
    public boolean contains(Object o) {
        int i = indexFor(o);
        return i>=0;//返回值为-1说明这个元素不存在
    }

    /**
     * 根据数组元素查询其对应的数组下标
     * @param o
     * @return
     */
    public int indexFor(Object o){
        //如果入参o为空,则查询数组中第一个为空的元素并返回对应的数组下标
        if(null==o){
            for(int i = 0; i < size; i++){
                if(arr[i]==null)
                    return i;
            }
        }else {//如果入参o不为空,则查询数组中与元素o相匹配的元素
            for(int i = 0; i < size; i++){
                if(o.equals(arr[i])){
                    return i;
                }
            }
        }
        //如果并没有在数组中找到元素o,则返回-1
        return -1;
    }

    @Override
    public Iterator iterator() {
        return null;
    }

    @Override
    public Object[] toArray() {
        return Arrays.copyOf(arr, size);
    }

    /**
     * 向数组中添加元素t
     * @param t
     * @return
     */
    @Override
    public boolean add(T t) {
        //先判断数组是否满了(即开辟的数组空间是否还可以继续存放元素)
        if(size>=arr.length){//如果满了,则扩容
            resize();
        }
        //在数组末尾添加元素t
        arr[size++] = t;
        return true;
    }

    /**
     * 判断是否需要扩容
     */
    public boolean shouldResize(int resize){
        //如果数组长度大于容量*扩容系数,则进行扩容
        if(resize>resizeCoefficient*capacity){
            return true;
        }else {
            return false;
        }

    }
    //对数组进行扩容,容量为原数组容量的两倍
    public void resize(){
        //1.声明一个是原来数组两倍的新数组
       /* T[] newArr = (T[]) new Object[capacity<<1];
        //2.将旧数组中的元素拷贝到新数组中(深拷贝)
        System.arraycopy(arr, 0, newArr, 0, capacity);

        //3.将原数组覆盖
        arr = newArr;*/

        int oldCapacity = arr.length;
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        if(newCapacity<=0){
            newCapacity = 10;
        }
        // minCapacity is usually close to size, so this is a win:
        arr = Arrays.copyOf(arr, newCapacity);
    }

    /**
     * 删除数组中某个元素
     * @param o 数组中的元素
     * @return
     */
    @Override
    public boolean remove(Object o) {
        for(int i =0;arr.length<size;i++){
            if(o.equals(arr[i])){
                this.fastRemove(i);
                return true;
            }
        }
        return false;
    }

    /**
     * 根据数组下标快速删除元素
     * @param index 数组下标
     */
    private void fastRemove(int index) {
        rangeCheck(index);//检查数组下标是否越界
        //如果一个数组为[1,3,5,9,13]要删除元素3(下标为1),则需要将所有元素3后面的元素都往前移动一个位置,
        // 那么需要拷贝的元素就是元素3后面的所有元素,需要拷贝的元素个数为:数组大小5 - 数组下标1 - 1 = 3
        int numMoved = size - index - 1;
        if (numMoved > 0)
            //1.调用本地方法对数组进行深拷贝,将所有在需要删除的元素的后面的数组元素往前移动一个位置
            System.arraycopy(arr, index+1, arr, index,
                    numMoved);
        //2.将需要删除的元素设置为null,交给垃圾回收机制回收
        arr[--size] = null; // clear to let GC do its work
    }

    /**
     * 将数组与集合collection合并到数组末尾元素后边
     * Collection<? extends T> collection 声明所有集合元素可以是泛型T的子类
     * @param collection
     * @return
     */
    @Override
    public boolean addAll(Collection<? extends T> collection) {
        //将集合元素collection转化为数组
        Object[] newArr = collection.toArray();
        //1.先判断是否需要扩容
        if(size+newArr.length>=capacity){
            resize();
        }
        //2.将所有集合元素拷贝到数组元素的末尾后边
        System.arraycopy(newArr,0,arr,size,newArr.length);
        size+=newArr.length;
        return false;
    }

    @Override
    public boolean addAll(int index, Collection c) {
        return false;
    }

    /**
     * 删除所有数组中的元素
     */
    @Override
    public void clear() {
        //1.将数组中的所有元素都设置为null,方便垃圾回收机制回收
        for(int i = 0; i <arr.length; i++){
            arr[i] = null;
        }
        //2.设置数组大小为0
        size = 0;
    }

    @Override
    public T get(int index) {
        return (T)arr[index];
    }

    @Override
    public Object set(int index, Object element) {
        return null;
    }

    @Override
    public void add(int index, Object element) {

    }

    /**
     * 根据数组元素下标删除指定的元素
     * @param index
     * @return 被删除的元素
     */
    @Override
    public T remove(int index) {

        fastRemove(index);
        return (T)arr[index];

    }

    @Override
    public int indexOf(Object o) {
        return 0;
    }

    @Override
    public int lastIndexOf(Object o) {
        return 0;
    }

    @Override
    public ListIterator listIterator() {
        return null;
    }

    @Override
    public ListIterator listIterator(int index) {
        return null;
    }

    @Override
    public List subList(int fromIndex, int toIndex) {
        return null;
    }

    @Override
    public boolean retainAll(Collection c) {
        return false;
    }

    @Override
    public boolean removeAll(Collection c) {
        return false;
    }

    @Override
    public boolean containsAll(Collection c) {
        return false;
    }

    @Override
    public Object[] toArray(Object[] a) {
        return new Object[0];
    }

    /**
     * 将数组转为字符串
     * @return
     */
    public  static String arrayToString(Object[] a){
        StringBuilder sb = new StringBuilder();
        if(a==null||a.length==0){
            return "[]";
        }
        sb.append("[");
        for(int i = 0; i < a.length;i++){
            sb.append(a[i]);
        }
        String s = sb.append("]").toString();
        return  s;
    }

    @SuppressWarnings("unchecked")
    T arr(int index) {
        return (T) arr[index];
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值