数组实现一个线性表

我的

package day309;

import java.util.Arrays;
import java.util.NoSuchElementException;

/**
 * 用数组实现一个线性表
 */
public class MyList<E> implements MyListInterface<E> {
    
    

    private final int MAX_CAPACITY = Integer.MAX_VALUE - 8;// 最大阈值
    private Object[] arrs;// 底层数组
    private int size; // 这个链表存储了多少元素

    public int getSize() {
    
    
        return size;
    }

    public int getLength() {
    
    
        return arrs.length;
    }


    @Override
    public String toString() {
    
    
        return "MyList{" +
                "arrs=" + Arrays.toString(arrs) +
                '}';
    }

    public MyList(int initCapacity) {
    
    
        if (initCapacity <= 0 || initCapacity > MAX_CAPACITY) {
    
    
            throw new IllegalArgumentException("initCapacity = " + initCapacity);
        }
        this.arrs = new Object[initCapacity];
    }

    @Override
    public boolean add(E o) {
    
    
        if (o == null) {
    
    
            throw new IllegalArgumentException("parame is null");
        }

        if (size == arrs.length) {
    
    
            int newLen = getLen();
            grow(newLen);
        }

        arrs[size] = o;
        size++;
        return true;
    }

    private void grow(int newLen) {
    
    

        // 创建一个新数组
        Object[] objects = new Object[newLen];
        // 把旧数组的数据转移到新数组
        for (int i = 0; i < arrs.length; i++) {
    
    
            objects[i] = arrs[i];
        }

        // 把新数组赋值给arr
        arrs = objects;

    }

//    private void grow(int newLen) {
    
    
//        Object[] objects = new Object[newLen];
//        System.arraycopy(arrs, 0, objects, 0, arrs.length);
//    }

    private int getLen() {
    
    
        int oldLen = arrs.length;
        int newLen = oldLen << 1;
        if (newLen < 0 || newLen > MAX_CAPACITY) {
    
    
            newLen = MAX_CAPACITY;
        }
        if (oldLen == newLen) {
    
    
            throw new RuntimeException("arrs is max");

        }
        return newLen;
    }

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

        if (size == arrs.length) {
    
    
            int newLen = getLen();
            grow(newLen);
        }
        System.arraycopy(arrs, index, arrs, index + 1, size - index);
        arrs[index] = element;
        size++;
    }

    @Override
    public void clear() {
    
    
        for (int i = 0; i < size; i++) {
    
    
            arrs[i] = null;
        }
        size = 0;
    }

    @Override
    public boolean contains(Object o) {
    
    
        if (o == null) {
    
    
            for (int i = 0; i < size; i++) {
    
    
                if (arrs[i] == null) return true;
            }
        } else {
    
    
            for (int i = 0; i < size; i++) {
    
    
                if (o.equals(arrs[i])) return true;
            }
        }
        return false;
    }

    @Override
    public E get(int index) {
    
    
        if (index > size || index < 0) {
    
    
            System.out.println("-1");
            throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
        }
        return (E) arrs[index];
    }

    @Override
    public int indexOf(Object o) {
    
    
        if (o == null) {
    
    
            for (int i = 0; i < size; i++) {
    
    
                if (arrs[i] == null) return i;
            }
        } else {
    
    
            for (int i = 0; i < size; i++) {
    
    
                if (o.equals(arrs[i])) return i;
            }
        }
        return -1;
    }

    @Override
    public int lastIndexOf(Object o) {
    
    
        if (o == null) {
    
    
            for (int i = size - 1; i > 0; i--) {
    
    
                if (arrs[i] == null) {
    
    
                    return i;
                }
            }
        } else {
    
    
            for (int i = size - 1; i > 0; i--) {
    
    
                if (o.equals(arrs[i])) {
    
    
                    return i;
                }
            }
        }
        return -1;
    }

    @Override
    public boolean isEmpty() {
    
    
        return size == 0;
    }

    @Override
    public E remove(int index) {
    
    
        if (index > size || index < 0) {
    
    
            System.out.println("-1");
            throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
        }
        E oldValue = (E) arrs[index];
        int numMoved = size - 1 - index;
        if (numMoved > 0)
            System.arraycopy(arrs, index + 1, arrs, index, numMoved);

        arrs[size - 1] = null;
        return oldValue;
    }

    @Override
    public boolean remove(Object str) {
    
    
        if (str == null) {
    
    
            for (int index = 0; index < size; index++) {
    
    
                if (size - index - 1 > 0) {
    
    
                    return remove2(index);
                }
            }

        } else {
    
    
            for (int i = 0; i < size; i++) {
    
    
                if (str.equals(arrs[i])) {
    
    
                    return remove2(i);
                }
            }
        }
        return false;
    }

    private boolean remove2(int i) {
    
    
        System.arraycopy(arrs, i + 1, arrs, i, size - i - 1);
        arrs[--size] = null;
        return true;
    }

    @Override
    public Object set(int index, Object element) {
    
    
        if (index > size || index < 0) {
    
    
            System.out.println("-1");
            throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
        }
        arrs[index] = element;
        return null;
    }

    @Override
    public int size() {
    
    
        return getSize();
    }

    @Override
    public MyIterator iterator() {
    
    
        return new Itr(0);
    }

    class Itr implements MyIterator<E> {
    
    
        int cursor;   // 下一个遍历的元素
        int lastRet = -1;// 刚刚遍历过的元素

        //构造方法
        public Itr(int index) {
    
    
            this.cursor = index;
        }

        @Override
        public boolean hasNext() {
    
    
            return cursor < size;
        }

        @Override
        public E next() {
    
    
            lastRet = cursor;
//            int i = cursor;
            cursor = cursor + 1;
//            lastRet = i;
            return (E) arrs[lastRet];
        }

        @Override
        public boolean hasPrevious() {
    
    
            return cursor != 0;
        }

        @Override
        public E previous() {
    
    
            if (!hasPrevious()) {
    
    
                throw new NoSuchElementException();
            }
            lastRet = --cursor;
            return (E) arrs[lastRet];
        }

        @Override
        public int nextIndex() {
    
    
            return cursor;
        }

        @Override
        public int previousIndex() {
    
    
            return cursor - 1;
        }

        @Override
        public void add(E e) {
    
    
            MyList.this.add(cursor, 0);
            cursor++;
            lastRet = -1;
        }

        /**
         * 删除最近返回的元素
         */
        @Override
        public void remove() {
    
    
            MyList.this.remove(lastRet);
            cursor = lastRet;
            lastRet = -1;
        }

        @Override
        public void set(E e) {
    
    
            arrs[lastRet] = e;
        }

    }

    @Override
    public MyIterator iterator(int index) {
    
    
        return new Itr(index);
    }
}

参考

package day309.Demo;

import java.util.ConcurrentModificationException;
import java.util.NoSuchElementException;

/**
 * @author     :snow
 * @date       :Created in 2021/2/2
 * @description: 一个手动仿照源代码思想实现的ArrayList集合类型
 * @modified By:snow
 * @version:    2.0
 */
public class MyArrayList<E> implements MyListInterface<E>  {
    
    
    private static final int DEFAULT_CAPACITY = 10;// 默认容量
    private static final int MAX_CAPACITY = Integer.MAX_VALUE - 8;// 最大容量

    private Object[] elements;// ArrayList底层持有的数组
    private int size;// ArrayList存储的数据元素数量
    private int modCount;

    public MyArrayList() {
    
    
        elements = new Object[DEFAULT_CAPACITY];
    }

    public MyArrayList(int initialCapacity) {
    
    
        if (initialCapacity <= 0 || initialCapacity > MAX_CAPACITY) {
    
    
            throw new IllegalArgumentException("initialCapacity=" + initialCapacity);
        }
        elements = new Object[initialCapacity];
    }


    /**
     * 在末尾添加元素
     * @param e 待添加的元素
     * @return 如果添加成功返回true, 否则返回false
     */
    @Override
    public boolean add(E e) {
    
    
        int oldSize = size;
        add(size, e);
        return oldSize < size;
    }

    /**
     * 在指定的索引位置添加元素
     * @param index 索引
     * @param e     待添加的元素
     */
    @Override
    public void add(int index, E e) {
    
    
        // 检查索引
        checkIndexForAdd(index);
        // 判断是否需要扩容
        if (size == elements.length) {
    
    
            // 计算新数组的大小
            int minCapacity = size + 1;
            // calculateCapacity: 计算扩容之后的长度
            int newLength = calculateCapacity(minCapacity);
            // 根据给定扩容长度扩容
            grow(newLength);
        }
        // 添加元素
        // 移动添加位置之后的元素(后移一位)
        for (int i = size; i > index; i--) {
    
    
            elements[i] = elements[i - 1];
        }
        elements[index] = e;
        size++;
        modCount++;
    }

    /**
     * 把整个MyArrayList中存储的元素全部清除
     */
    @Override
    public void clear() {
    
    
        for (int i = 0; i < size; i++) {
    
    
            elements[i] = null;
        }
        size = 0;
        modCount++;
    }

    /**
     * 判断集合中是否有与指定对象相等的元素
     * @param e 指定对象
     * @return 如果集合中存在这样的元素返回true, 否则返回false
     */
    @Override
    public boolean contains(E e) {
    
    
        return indexOf(e) != -1;
    }

    /**
     * 获取指定索引位置的元素
     * @param index 索引
     * @return 指定索引位置的元素
     */
    @Override
    public E get(int index) {
    
    
        checkIndex(index);
        return (E) elements[index];
    }

    /**
     * 参数合法检验
     * @param index 下标位置
     */
    private void checkIndex(int index) {
    
    
        if (index < 0 || index >= size) {
    
    
            throw new IllegalArgumentException("index=" + index + ", size=" + size);
        }
    }

    /**
     * 获取第一个与指定对象相等元素的索引
     * @param e 指定对象
     * @return 第一个与指定对象相等元素的索引, 如果不存在返回-1.
     */
    @Override
    public int indexOf(E e) {
    
    
        if (e == null) {
    
    
            for (int i = 0; i < size; i++) {
    
    
                if (elements[i] == null) return i;
            }
        } else {
    
    
            for (int i = 0; i < size; i++) {
    
    
                if (e.equals(elements[i])) return i;
            }
        }
        return -1;
    }

    /**
     * 获取最后一个与指定对象相等元素的索引
     * @param e 指定对象
     * @return 最后一个与指定对象相等元素的索引, 如果不存在返回-1.
     */
    @Override
    public int lastIndexOf(E e) {
    
    
        if (e == null) {
    
    
            for (int i = size - 1; i >= 0; i--) {
    
    
                if (elements[i] == null) return i;
            }
        } else {
    
    
            for (int i = size - 1; i >= 0; i--) {
    
    
                if (e.equals(elements[i])) return i;
            }
        }
        return -1;
    }

    /**
     * 判空
     * @return 如果集合为空返回true, 否则返回false
     */
    @Override
    public boolean isEmpty() {
    
    
        return size == 0;
    }

    /**
     * 删除指定索引位置的元素
     * @param index 索引
     * @return 被删除的元素
     */
    @Override
    public E remove(int index) {
    
    
        checkIndex(index);
        E removeValue = (E) elements[index];
        // 移动删除位置之后的元素: 前移一位,
        for (int i = index; i < size - 1; i++) {
    
    
            elements[i] = elements[i + 1];
        }

        // 最后一个元素置为null
        elements[size - 1] = null; // Caution!
        size--;
        modCount++;
        return removeValue;
    }

    /**
     * 删除第一个与指定对象相等的元素
     * @param e 指定对象
     * @return 如果删除成功返回true, 否则返回false
     */
    @Override
    public boolean remove(E e) {
    
    
        // 获得该内容对应的下标
        int index = indexOf(e);
        if (index == -1) return false;
        // 根据下标删除元素
        remove(index);
        return true;
    }

    /**
     * 替换指定索引位置的元素
     * @param index 索引
     * @param e     新值
     * @return 旧值
     */
    @Override
    public E set(int index, E e) {
    
    
        // 检查索引
        checkIndex(index);
        E oldValue = (E) elements[index];
        elements[index] = e;
        return oldValue;
    }

    /**
     * 获取集合中元素的个数
     * @return 集合中元素的个数
     */
    @Override
    public int size() {
    
    
        return size;
    }

    /**
     * 获取迭代器, 光标位于索引为 0 的元素的前面
     * @return 迭代器
     */
    @Override
    public MyIterator<E> iterator() {
    
    
        return new Itr(0);
    }

    /**
     * 获取迭代器, 光标位于索引为index元素的前面
     * @param index 索引
     * @return 迭代器
     */
    @Override
    public MyIterator<E> iterator(int index) {
    
    
        checkIndexForAdd(index);
        return new Itr(index);
    }


    private class Itr implements MyIterator<E> {
    
    
        // 属性
        int cursor; //光标后面元素的索引
        int expModCount = modCount;
        int lastRet = -1; //-1表示最近没有返回元素,或者是最近返回的元素已经失效。

        // 构造方法
        Itr(int index) {
    
    
            cursor = index;
        }

        /**
         * 判断光标后面是否还有元素
         * @return 如果还有元素返回true, 否则返回false
         */
        @Override
        public boolean hasNext() {
    
    
            return cursor != size;
        }

        /**
         * 将光标往后移动一步, 并返回光标越过的元素
         * @return 光标越过的元素
         */
        @Override
        public E next() {
    
    
            // 判断迭代器是否有效
            checkConModException();
            // 判断光标后面是否还有元素
            if (!hasNext()) {
    
    
                throw new NoSuchElementException();
            }
            lastRet = cursor;
            cursor++;
            return (E) elements[lastRet];
        }


        /**
         * 检查在这次迭代过程中, 源MyArrayList的数据是否被别的数据修改了
         */
        private void checkConModException() {
    
    
            if (expModCount != modCount) {
    
    
                throw new ConcurrentModificationException();
            }
        }

        /**
         * 判断光标前面是否还有元素
         * @return 如果还有元素返回true, 否则返回false
         */
        @Override
        public boolean hasPrevious() {
    
    
            return cursor != 0;
        }

        /**
         * 将光标往前移动一步, 并返回光标越过的元素
         * @return 光标越过的元素
         */
        @Override
        public E previous() {
    
    
            // 检查并发修改异常
            checkConModException();
            // 判断光标前面是否还有元素
            if (!hasPrevious()) {
    
    
                throw new NoSuchElementException();
            }
            // 移动光标
            lastRet = --cursor;
            return (E) elements[lastRet];
        }

        /**
         * 获取光标后面元素的索引
         * @return 光标后面元素的索引
         */
        @Override
        public int nextIndex() {
    
    
            return cursor;
        }

        /**
         * 获取光标前面元素的索引
         * @return 光标前面元素的索引
         */
        @Override
        public int previousIndex() {
    
    
            return cursor - 1;
        }

        /**
         * 在光标后面添加元素
         * @param e 待添加的元素
         */
        @Override
        public void add(E e) {
    
    
            checkConModException();
            MyArrayList.this.add(cursor, e);
            // 修改迭代器的属性
            expModCount = modCount;
            cursor++;
            lastRet = -1;
        }

        /**
         * 删除最近返回的元素
         */
        @Override
        public void remove() {
    
    
            checkConModException();
            if (lastRet == -1) {
    
    
                throw new IllegalStateException();
            }
            MyArrayList.this.remove(lastRet);
            // 修改迭代器的属性
            expModCount = modCount;
            cursor = lastRet;
            lastRet = -1;
        }

        /**
         * 替换最近返回的元素
         * @param e 新值
         */
        @Override
        public void set(E e) {
    
    
            checkConModException();
            if (lastRet == -1) {
    
    
                throw new IllegalStateException();
            }
            // 替换元素
            elements[lastRet] = e;
        }
    }

    /**
     * 扩容方法
     * @param newLength 新的数组容量
     */
    private void grow(int newLength) {
    
    
        Object[] newTable = new Object[newLength];
        // 复制元素
        for (int i = 0; i < size; i++) {
    
    
            newTable[i] = elements[i];
        }
        // elements指向新数组
        elements = newTable; // Caution!
    }

    /**
     * 计算数组扩容需要的新容量
     * @param minCapacity
     * @return
     */
    private int calculateCapacity(int minCapacity) {
    
    
        if (minCapacity > MAX_CAPACITY || minCapacity < 0) {
    
    
            throw new IllegalArgumentException();
        }
        // 一定能够容纳minCapacity个元素
        // 变成原来的1.5倍
        int newLength = elements.length + (elements.length >> 1);

        // 判断扩容是否超过限定值
        if (newLength > MAX_CAPACITY || newLength < 0) {
    
    
            newLength = MAX_CAPACITY;
        }
        return newLength > minCapacity ? newLength : minCapacity;
    }

    /**
     * 参数检查方法
     * @param index 需要检查的下标
     */
    private void checkIndexForAdd(int index) {
    
    
        if (index < 0 || index > size) {
    
    
            throw new IllegalArgumentException("index=" + index + ", size=" + size);
        }
    }
}

猜你喜欢

转载自blog.csdn.net/AC_872767407/article/details/114607292