ArrayList的实现

ArrayList实现

  本文给出ArrayList的简单实现,ArrayList内部采用数组实现,因此具有较快的元素访问速度,但同时不利于元素的插入和删除,如当在最前端插入元素,会导致所有其余所有元素后移一位,造成N次迭代,复杂度O(N)。实现其简单的增删改查,提供自动扩充功能,并内置迭代器,可以进行增广遍历。

功能描述

  • 提供易于使用的ArrayList泛型实现,避免与类库冲突,命名为MyArrayList,其包含的主要细节如下:
    • MyArrayList保持基础数组,数组的容量,以及存储在MyArrayList中当前的项数;
    • MyArrayList设计一种机制用来改变数组容量,通过获得一个新数组,将老数组的内容复制到新数组,允许JVM回收老数组;
    • MyArrayList提供set和get的实现;
    • MyArrayList提供基本的例程。如size(), clear(), isEmpty()等典型的单行程序;同时提供remove和两个版本的add,一个在任意位置添加,一个在集合末端添加,并且数组容量不足,add方法将扩充数组;
    • MyArrayList提供一个实现Iterator接口的类,该类存储迭代序列中的下一个下标,并提供next, hasNext, remove方法实现。MyArrayList的迭代器方法直接返回实现Iterator接口的该类的一个新的实例,代码中采用两种方式,私有内部类和嵌套类实现迭代器。

代码实现

package com.yam.base;

import java.util.Iterator;
import java.util.NoSuchElementException;

/**
 * ArrayList的实现
 * @author: Ympery
 * @date: 2017/3/8 11:10.
 */
public class MyArrayList<AnyType> implements Iterable<AnyType> {

    /**
     * 默认大小
     */
    private static final int DEFAULT_CAPACITY = 10;

    /**
     * 集合大小
     */
    private int theSize;

    /**
     * 类型数组
     */
    private AnyType[] theItems;

    public MyArrayList() { clear(); }

    /**
     * 清理集合
     */
    public void clear() {
        theSize = 0;
        ensureCapacity(DEFAULT_CAPACITY);
    }

    /**
     * 返回集合容量
     * @return 大小
     */
    public int size() { return theSize; }

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

    /**
     * 将集合缩减到内容大小
     */
    public void trimToSize() { ensureCapacity(size()); }

    /**
     * 获取集合元素
     * @param idx 位置
     * @return
     */
    public AnyType get(int idx) {
        if (0 > idx || idx >= size())
            throw new ArrayIndexOutOfBoundsException();
        return theItems[idx];
    }

    /**
     * 根据元素位置设置该元素值
     * @param idx 位置
     * @param newVal 要设置的值
     * @return 该元素原有的值
     */
    public AnyType set(int idx, AnyType newVal) {
        if (0 > idx || idx >= size())
            throw new ArrayIndexOutOfBoundsException();
        AnyType old = theItems[idx];
        theItems[idx] = newVal;
        return old;
    }

    /**
     * 列表copy,容量的扩张和收缩
     * @param newCapacity
     */
    public void ensureCapacity(int newCapacity) {
        if (newCapacity < theSize)
            return;

        AnyType[] old = theItems;
        // 因为泛型数组的创建时非法的,因此创建一个有界数组,强制转换
        theItems = (AnyType[]) new Object[newCapacity];

        for (int i = 0; i < size(); i++)
            theItems[i] = old[i];
    }

    /**
     * 在list的末端插入x
     * @param x
     * @return
     */
    public boolean add(AnyType x) {
        add(size(), x);
        return true;
    }

    /**
     * 向集合中插入元素(任意位置)
     * @param idx
     * @param x
     */
    public void add(int idx, AnyType x) {
        /**
         * 判断当前元素个数,是否需要扩充集合大小
         */
        if (theItems.length == size())
            ensureCapacity(size() * 2 + 1);
        for (int i = theSize; i > idx; i--)
            theItems[i] = theItems[i - 1];
        theItems[idx] = x;

        theSize++;
    }

    /**
     * 删除指定位置元素
     * @param idx
     * @return
     */
    public AnyType remove(int idx) {
        AnyType removedItem = theItems[idx];
        for (int i = idx; i < size(); i++)
            theItems[i] = theItems[i++];
        theSize--;

        return removedItem;
    }


    /**
     * 获取一个当前集合的迭代器
     * @return
     */
    /*public Iterator<AnyType> iterator() {
        return new ArrayListIterator();
    }*/

    /**
     * 内部类构造集合迭代器
     */
    /*private class ArrayListIterator implements Iterator<AnyType>{

        *//**
         * 记录当前遍历位置
         *//*
        private int current = 0;

        */
    /**
     * 是否由下一个元素
     *
     * @return
     *//*
        @Override
        public boolean hasNext() {
            return current < theSize;
        }

        @Override
        public AnyType next() {
            if (!hasNext())
                throw new NoSuchElementException();
            return theItems[current++];
        }

        @Override
        public void remove() {
            MyArrayList.this.remove(--current);
        }
    }*/

    /**
     * 这里在获取迭代器必须传入该集合本身
     * @return
     */
    public ArrayListIterator<AnyType> iterator() {
        return new ArrayListIterator<>(this);
    }

    /**
     * 使用嵌套类构造集合迭代器
     * @param <AnyType>
     */
    private static class ArrayListIterator<AnyType> implements Iterator<AnyType> {

        /*
         * 当前位置
         */
        private int current = 0;
        private MyArrayList<AnyType> theList;

        public ArrayListIterator(MyArrayList list){
            theList = list;
        }

        @Override
        public boolean hasNext() {
            return current < theList.size();
        }

        @Override
        public AnyType next() {
            if (!hasNext())
                throw new NoSuchElementException();
            return theList.theItems[current++];
        }

        @Override
        public void remove() {
            theList.remove(--current);
        }
    }

    /**
     * 测试
     * @param args
     */
    public static void main(String[] args) {
        MyArrayList<Character> strList = new MyArrayList<>();
        char c = 'a';
        for (int i = 0; i < 15; i++)
            strList.add(c++);

        for(char ch : strList)
            System.out.print(ch + " ");

        System.out.println("删除之前:" + strList.size());

        strList.remove(5);

        for(char ch : strList)
            System.out.print(ch + " ");
        System.out.println("删除之后:" + strList.size());
    }
}

  注:代码中的注释部分是采用内部类迭代器实现,文章最后采用了嵌套类实现(我习惯吧静态内部类称作嵌套类),两者区别这里不做赘述。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值