自己实现ArrayList
Published on 2017-11-14 09:31 in 暂未分类 with 是奉壹呀

自己实现ArrayList

    思路:

    一 载体 

    ArrayList是一个集合容器,必然要有一个保存数据的载体。

    复制代码
    public class MyArraylist {
        private final static int INIT_COUNT = 10;
        
        Object[] arrays;
        
        public MyArraylist() {
            this(INIT_COUNT);
        }
    
        public MyArraylist(int count) {
            arrays = new Object[count];
        } 
    }
    复制代码

     

     

    二属性

    长度

    得到集合会初始化一个数组长度,集合的元素个数不能是数组长度。

    public class MyArraylist2 {
        private int size;
        public int size(){
            return size;
        }
        
    }

     

     

    三方法

    增删改查

    增加

    按默认索引加入元素,按索引加入元素,加入单个元素,加入批量元素。这里只举按单个加入元素的例子。

    首先需要判断索引是否非法

    复制代码
    public void checkIndexRange(int index) {
            if (index > size) {
                throw new IndexOutOfBoundsException("数组越界");
            }
        }
    
        public void checkIndexRangeForAdd(int index) {
            if (index > size || index < 0) {
                throw new IndexOutOfBoundsException("数组越界");
            }
    }
    复制代码

    判断当前数组是否需要扩容。如果索引大于当前数组长度,按当前长度的50%增加。并将当前数组复制到新的数组。

    public void checkIndex(int index) {
            if (index > arrays.length) {
                int oldLength = size;
                int newLength = oldLength + (index >> 1);
                arrays = Arrays.copyOf(arrays, newLength);
            }
        }

     

    增加单个元素

    复制代码
        public void add(Object obj, int index) {
            checkIndexRangeForAdd(index);//判断索引是否非法
            checkIndex(size + 1);//判断数组是否需要扩容
            System.arraycopy(arrays, index, arrays, index + 1, size - index);
            arrays[index] = obj;
            size++;
        }
    
        public boolean add(Object obj) {
            checkIndex(size + 1);//判断数组是否需要扩容
            arrays[size++] = obj;
            return true;
        }
    复制代码

     

    获取元素

    public T get(int index) {
            checkIndexRangeForAdd(index);
            return (T) arrays[index];
        }

     

    更新元素

        public T set(Object obj, int index) {
            checkIndexRange(index);
            T t = (T) arrays[index];
            arrays[index] = obj;
            return t;
        }

     

    删除元素

    复制代码
    public T remove(int index) {
            checkIndexRange(index);
    
            T t = (T) arrays[index];
            int moveLength = size - index - 1;
            if (moveLength > 0) {
                System.arraycopy(arrays, index + 1, arrays, index, moveLength);
            }
            arrays[--size] = null;
            return t;
        }
    复制代码

     

    四迭代

    使用增强型for循环迭代输出,以及Java 8引进的lambda表达式实现foreach。

     

    首先生成一个迭代器。

    复制代码
    private class MyArrayListIterator implements Iterator<T> {
    
            private int count;
     
            public boolean hasNext() {
                return count != size;
            }
    
            public T next() {
                checkModcount();
                return (T) arrays[count++];
            } 
             
        }
    复制代码

    然后继承Iterable接口。

    复制代码
    public class MyArraylist2<T> implements Iterable<T>{
     
    
        @Override
        public Iterator<T> iterator() {
            return new MyArrayListIterator();
        }
    
         
        
    }
    复制代码

     

     

     

    五线程安全问题

    ArrayList没有实现线程安全,但是在迭代的时候,不允许修改。

    ArrayList使用一个成员变量modCount在迭代开始的时候记录ArrayList正在做修改(增加,修改,删除)的数量,然后在每迭代一行的时候,去比较modCount是否发生变化。如果发生变化,证明此刻有其它的线程或者就是本线程就对它进行修改,然后抛出异常。

    定义modcount变量。

    private transient int modcount;

    在增加,修改,删除的时候,均需将此值加1。

     

    复制代码
    public boolean add(Object obj) {
            checkIndex(size + 1);
            modcount++;//加1
            arrays[size++] = obj;
            return true;
        }
    
        public void checkIndex(int index) {
            if (index > arrays.length) {
                modcount++;//加1
                int oldLength = size;
                int newLength = oldLength + (index >> 1);
                arrays = Arrays.copyOf(arrays, newLength);
            }
        }
    复制代码

     

    public T set(Object obj, int index) {
            checkIndexRange(index);
            modcount++;//加1
            T t = (T) arrays[index];
            arrays[index] = obj;
            return t;
        }

     

    复制代码
    public T remove(int index) {
            checkIndexRange(index);
            modcount++;//加1
    
            @SuppressWarnings("unchecked")
            T t = (T) arrays[index];
            int moveLength = size - index - 1;
            if (moveLength > 0) {
                System.arraycopy(arrays, index + 1, arrays, index, moveLength);
            }
            arrays[--size] = null;
            return t;
        }
    复制代码

     

    在迭代的时候,将此值赋给另一个变量exceptCount。然后再每迭代一行的时候,将exceptCount与modcount比较。

    复制代码
    private class MyArrayListIterator implements Iterator<T> {
    
         
    
            private int exceptCount = modcount; 
    
            public void checkModcount() {
                if (exceptCount != modcount) {
                    throw new ConcurrentModificationException();
                }
            }
    
        }
    复制代码

     

    最后实现的全部代码

    复制代码
    package com.skycomm.sdf;
    
    import java.util.Arrays;
    import java.util.ConcurrentModificationException;
    import java.util.Iterator;
    
    public class MyArraylist<T> implements Iterable<T> {
    
        private final static int INIT_COUNT = 10;
    
        private int size = 0;
    
        private transient int modcount;
    
        Object[] arrays;
    
        public MyArraylist() {
            this(INIT_COUNT);
        }
    
        public MyArraylist(int count) {
            arrays = new Object[count];
        }
    
        public void add(Object obj, int index) {
            checkIndexRangeForAdd(index);
            checkIndex(size + 1);
            System.arraycopy(arrays, index, arrays, index + 1, size - index);
            arrays[index] = obj;
            size++;
        }
    
        public boolean add(Object obj) {
            checkIndex(size + 1);
            modcount++;//加1
            arrays[size++] = obj;
            return true;
        }
    
        public void checkIndex(int index) {
            if (index > arrays.length) {
                modcount++;//加1
                int oldLength = size;
                int newLength = oldLength + (index >> 1);
                arrays = Arrays.copyOf(arrays, newLength);
            }
        }
    
        public T get(int index) {
            checkIndexRangeForAdd(index);
            return (T) arrays[index];
        }
    
        public T remove(int index) {
            checkIndexRange(index);
            modcount++;//加1
    
            @SuppressWarnings("unchecked")
            T t = (T) arrays[index];
            int moveLength = size - index - 1;
            if (moveLength > 0) {
                System.arraycopy(arrays, index + 1, arrays, index, moveLength);
            }
            arrays[--size] = null;
            return t;
        }
    
        public T set(Object obj, int index) {
            checkIndexRange(index);
            modcount++;//加1
            T t = (T) arrays[index];
            arrays[index] = obj;
            return t;
        }
    
        public void checkIndexRange(int index) {
            if (index > size) {
                throw new IndexOutOfBoundsException("数组越界");
            }
        }
    
        public void checkIndexRangeForAdd(int index) {
            if (index > size || index < 0) {
                throw new IndexOutOfBoundsException("数组越界");
            }
        }
    
        public int size() {
            return size;
        }
    
        public boolean isEmpty() {
            return size == 0;
        }
    
        public String toString() {
            Iterator<T> it = iterator();
            if (!it.hasNext())
                return "[]";
    
            StringBuilder sb = new StringBuilder();
            sb.append('[');
            for (;;) {
                T e = it.next();
                sb.append(e == this ? "(this Collection)" : e);
                if (!it.hasNext())
                    return sb.append(']').toString();
                sb.append(',').append(' ');
            }
        }
    
        public Iterator<T> iterator() {
            return new MyArrayListIterator();
        }
    
        private class MyArrayListIterator implements Iterator<T> {
    
            private int count;
    
            private int exceptCount = modcount;
    
            public boolean hasNext() {
                return count != size;
            }
    
            public T next() {
                checkModcount();
                return (T) arrays[count++];
            }
    
            public void checkModcount() {
                if (exceptCount != modcount) {
                    throw new ConcurrentModificationException();
                }
            }
    
        }
    
    }
    View Code
    复制代码

     

    posted @   是奉壹呀  阅读(207)  评论(0编辑  收藏  举报
    编辑推荐:
    · 如何编写易于单元测试的代码
    · 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
    · .NET Core 中如何实现缓存的预热?
    · 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
    · AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
    阅读排行:
    · 周边上新:园子的第一款马克杯温暖上架
    · Open-Sora 2.0 重磅开源!
    · .NET周刊【3月第1期 2025-03-02】
    · 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
    · [AI/GPT/综述] AI Agent的设计模式综述
    点击右上角即可分享
    微信分享提示