zoukankan      html  css  js  c++  java
  • 自己实现ArrayList

    在ArrayList源码中主要的两个属性是 Object数组和元素个数,

    elementData 用transient修饰的原因:当数组长度为10,这时候只有5个元素,默认序列化会占用10个空间。用transient修饰后,再重写writeOjbect和readObject可以自己定义序列化逻辑,节省空间
        transient Object[] elementData; 
    
        private int size;

    自己实现的 ArrayList, 少了很多检查,比如数组下标越界

    System.arraycopy(elementData, index + 1, elementData, index, numMoved);   这是个native方法

     Arrays.copyOf(elementData, newCapacity);  这个方法内部是转调System.arraycopy方法

    在源码中数组扩容是增加为原来的1.5倍,扩容时候用到了>> 右移操作,就是将一个数减少一半。假如数组初始大小为1,会做额外的判断

    public class MyArrayList<E> implements Iterable<E> {
    
        Object[] elementData;
    
        int size;
    
        public MyArrayList() {
            elementData = new Object[10];
            size = 0;
        }
    
        public void add(Object obj) {
            ensureExplicitCapacity(size + 1);
            elementData[size++] = obj;
        }
    
        private void ensureExplicitCapacity(int minCapacity) {
            if (size == elementData.length) {
                // 原来本身elementData容量大小 2
                int oldCapacity = elementData.length;
                // 新数据容量大小 (oldCapacity >> 1)=oldCapacity/
                int newCapacity = oldCapacity + (oldCapacity >> 1);// (2+2/2)=3
                // 如果初始容量为1的时候,那么他扩容的大小为多少呢?
                if (newCapacity - minCapacity < 0)
                    newCapacity = minCapacity; // 最少保证容量和minCapacity一样
                // 将老数组的值赋值到新数组里面去
                elementData = Arrays.copyOf(elementData, newCapacity);
            }
        }
    
        public Object remove(int index) {
            Object object = get(index);// index 2
            // 计算删除元素后面的长度
            int numMoved = size - index - 1; // 5
            // 2.删除原理 使用arraycopy往前移动数据,将最后一个变为空
            if (numMoved > 0)
                System.arraycopy(elementData, index + 1, elementData, index, numMoved);
            elementData[--size] = null; // 将最后一个元素变为空
            return object;
        }
    
        public Object get(int index) {
            return elementData[index];
        }
    
        @Override
        public Iterator<E> iterator() {
            Iterator<E> iterator = new Iterator<E>() {
                int index = 0;
    
                @Override
                public boolean hasNext() {
                    if (index < size) {
                        return true;
                    } else {
                        return false;
                    }
                }
    
                @SuppressWarnings("unchecked")
                @Override
                public E next() {
                    return (E) elementData[index++];
                }
            };
            return iterator;
        }
    
        public static void main(String[] args) {
    
            MyArrayList<Integer> list = new MyArrayList<Integer>();
            for (int i = 10; i < 23; i++) {
                list.add(i);
            }
    
            Iterator<Integer> iterator = list.iterator();
            while (iterator.hasNext()) {
                System.out.print(iterator.next() + "   ");
            }
            System.out.println();
            System.out.println(list.get(5));
    
            list.remove(6);
            Iterator<Integer> iterator2 = list.iterator();
            while (iterator2.hasNext()) {
                System.out.print(iterator2.next() + "   ");
            }
    
        }
    }
  • 相关阅读:
    校门外的树-poj
    [编程题]股票交易日
    2017计算机学科夏令营上机考试-C:岛屿面积
    2017计算机学科夏令营上机考试-B编码字符串
    2017计算机学科夏令营上机考试-A判决素数个数
    2017中国移动校园招聘考试试题一
    2017第八届蓝桥杯B组省赛C/C++程序设计大赛题解
    西科旧事的博客
    第八届蓝桥杯省赛题解
    微信小程序中的 event.target和event.currentTarget区别?
  • 原文地址:https://www.cnblogs.com/moris5013/p/11062832.html
Copyright © 2011-2022 走看看