实现MyArrayList类深入理解ArrayList

ArrayList简介

ArrayList是一个动态数组,Array的复杂版本,它提供了动态的增加和减少元素,实现了ICollection和IList接口,灵活的设置数组的大小等好处,ArrayList不是线程安全的。

MyArrayList

在实现MyArrayList前先实现MyList,MyAbstractList,他们的关系如下。

MyArrayList--->(继承于)MyAbstractList--->(实现)MyList接口--->(实现)java.lang.Iterable接口

 

通过编写新的ArrayList来实现java中ArrayList的部分功能

MyList接口定义如下

 

public interface MyList<E> extends Iterable<E> {

    public void add(E e);
    public void add(int index, E e);
    public void clear();
    public boolean contains(E e);
    public E get(int index);
    public int indexOf(E e);
    public boolean isEmpty();
    public int lastIndexOf(E e);
    public boolean remove(E e);
    public E remove(int index);
    public E set(int index, E e);
    public int size();
}

 

MyAbstractList类定义如下

 

public abstract class MyAbstractList<E> implements MyList<E> {

    protected int size = 0;
    
    protected MyAbstractList() {
        
    }
    
    protected MyAbstractList(E[] objects) {
        for(int i = 0; i < objects.length; i++) {
            add(objects[i]);
        }
    }
    
    @Override
    public void add(E e) {
        add(size, e);
    }
    
    @Override
    public boolean isEmpty() {
        return size == 0;
    }
    
    @Override
    public int size() {
        return size;
    }
    
    @Override
    public boolean remove(E e) {
        if(indexOf(e) >= 0) {
            remove(indexOf(e));
            return true;
        }else {
            return false;
        }
    }
}

MyArrayList定义如下

import java.util.Iterator;

public class MyArrayList<E> extends MyAbstractList<E> {
    public static final int INITIAL_CAPACITY = 16;//初始容量
    private E[]data = (E[])(new Object[INITIAL_CAPACITY]);;
    
    public MyArrayList() {
    }
    
    public MyArrayList(int length) {
        if(length >= 0) {
            data = (E[])(new Object[length]);
        }
    }
    
    public MyArrayList(E[] objects) {
        for(int i = 0; i < objects.length; i++) {
            add(objects[i]);
        }
    }

    @Override
    public void add(int index, E e) {
        // TODO Auto-generated method stub
        ensureCapacity();
        
        for(int i = size - 1; i >= index; i--) {//将data[index]和后面的元素往后移动一位
            data[i + 1] = data[i];
        }
        
        data[index] = e;
        size++;
    }

    //判断容量满时,新建一个容量为原来两倍+1的数组
    private void ensureCapacity() {
        if(size >= data.length) {
            E[] newData = (E[])(new Object[size * 2 + 1]);//java源码扩容1.5倍+1
            System.arraycopy(data, 0, newData, 0, size);
            data = newData;
        }
    }
    
    @Override
    public void clear() {
        // TODO Auto-generated method stub
        data = (E[])(new Object[INITIAL_CAPACITY]);
        size = 0;
    }

    @Override
    public boolean contains(E e) {
        // TODO Auto-generated method stub
        for(int i = 0; i < size; i++) {
            if(e.equals(data[i])) {
                return true;
            }
        }
        return false;
    }

    @Override
    public E get(int index) {
        // TODO Auto-generated method stub
        checkIndex(index);//判断下标是否合法
        return data[index];
    }

    private void checkIndex(int index) {
        if(index < 0 || index >= size) {
            throw new IndexOutOfBoundsException("index " + index + " out of bounds");
        }
    }
    
    @Override
    public int indexOf(E e) {
        // TODO Auto-generated method stub
        for(int i = 0; i < size; i++) {
            if(e.equals(data[i])) {
                return i;
            }
        }
        return -1;
    }

    @Override
    public int lastIndexOf(E e) {
        // TODO Auto-generated method stub
        for(int i = size - 1; i >= 0; i--) {
            if(e.equals(data[i])) {
                return i;
            }
        }
        return -1;
    }

    @Override
    public E remove(int index) {
        // TODO Auto-generated method stub
        checkIndex(index);//判断下标是否合法
        E e = data[index];//获取删除对象的值
        
        for(int i = index; i < size - 1; i++) {//将data[index]后面的元素往前移动一位
            data[i] = data[i+1];
        }
        
        data[size] = null;//删除最后的元素
        size--;
        return e;
    }

    @Override
    public E set(int index, E e) {
        // TODO Auto-generated method stub
        checkIndex(index);//判断下标是否合法
        E old = data[index];
        data[index] = e;
        return old;
    }

    //重写java.lang.Object.toString方法,打印整个数组
    @Override
    public String toString() {
        StringBuilder result = new StringBuilder("[");
        
        for(int i = 0; i < size; i++) {
            result.append(data[i]);
            if(i < size - 1) {
                result.append(",");
            }
        }
        
        return result + "]";
    }
    
    //新建一个刚好等于size的数组,即将数组容量设为刚好足够存放的大小
    public void trimToSize() {
        if(size != data.length) {
            E[] newData = (E[])(new Object[size]);
            System.arraycopy(data, 0, newData, 0, size);
            data = newData;
        }
    }
    
    @Override
    public Iterator<E> iterator() {
        // TODO Auto-generated method stub
        return new ArrayListIterator();
    }

    private class ArrayListIterator implements Iterator<E> {
        private int current = 0;

        @Override
        public boolean hasNext() {
            // TODO Auto-generated method stub
            return (current < size);
        }

        @Override
        public E next() {
            // TODO Auto-generated method stub
            return data[current++];
        }
    }
}

测试代码如下

public class TestMyArrayList {

    public static void main(String[] args) {
        // TODO Auto-generated method stub

//        String[] ss = {"China","America","Germany","Canada","France","Germany"};
        MyList<String> list = new MyArrayList<String>();
        System.out.println("测试add(E e)方法和add(int index, E e)方法添加数据。");
        list.add("America");
        list.add(0,"China");
        list.add("Canada");
        list.add("France");
        list.add(2,"Germany");
        list.add("Germany");
        System.out.println("通过toString()方法打印数组" + list.toString());
        System.out.println("通过size()方法获取长度:" + list.size());
        System.out.println("测试contains()方法:" + list.contains("France"));
        System.out.println("通过get()方法获取指定下标的值:" + list.get(1));
        System.out.println("通过indexOf()方法获取指定值的下标:" + list.indexOf("Germany"));
        System.out.println("通过lastIndexOf()方法获取最后出现的指定值的下标:" + list.lastIndexOf("Germany"));
        System.out.println("通过下标删除指定值:" + list.remove(5));
        System.out.println("删除后的数组:" + list.toString());
        System.out.println("通过set()方法修改值:" + list.set(2, "Russia"));
        System.out.print("通过foreach遍历数组:");
        for(String s:list) {
            System.out.print(s.toUpperCase() + " ");
        }
    }

}

测试结果

 

 

思考:为什么MyArrayList类中的ensureCapacity()扩容倍数是2 * x + 1而不是2 * x?

因为如果我们创建了一个长度为0的数组,如果扩容倍数是2 * x,那么这个数组就无法扩容了。

 

转载于:https://www.cnblogs.com/zhanghongcan/p/9026733.html

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用泛型实现MyArrayList类的示例代码: ```java public class MyArrayList<E> { private static final int DEFAULT_CAPACITY = 10; private int size; private E[] elements; public MyArrayList() { elements = (E[]) new Object[DEFAULT_CAPACITY]; } public MyArrayList(int capacity) { elements = (E[]) new Object[capacity]; } public void add(E e) { if (size == elements.length) { resize(); } elements[size++] = e; } public E get(int index) { checkIndex(index); return elements[index]; } public void set(int index, E e) { checkIndex(index); elements[index] = e; } public E remove(int index) { checkIndex(index); E element = elements[index]; for (int i = index; i < size - 1; i++) { elements[i] = elements[i + 1]; } elements[--size] = null; return element; } public boolean contains(E e) { for (int i = 0; i < size; i++) { if (elements[i].equals(e)) { return true; } } return false; } public int size() { return size; } public boolean isEmpty() { return size == 0; } private void resize() { E[] newElements = (E[]) new Object[elements.length * 2]; System.arraycopy(elements, 0, newElements, 0, size); elements = newElements; } private void checkIndex(int index) { if (index < 0 || index >= size) { throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size); } } } ``` 使用示例: ```java MyArrayList<String> list = new MyArrayList<>(); list.add("hello"); list.add("world"); System.out.println(list.get(0)); // output: hello list.set(1, "java"); System.out.println(list.get(1)); // output: java System.out.println(list.remove(0)); // output: hello System.out.println(list.contains("java")); // output: true System.out.println(list.size()); // output: 1 System.out.println(list.isEmpty()); // output: false ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值