我的集合学习笔记--ArrayList

一,ArrayList

实现自己的ArrayList:主要是添加方法,理解自动扩容机制

代码+注释

    package com.amazing.jdk.learn2List.list_08_13;  
      
    /** 
     * 1.实现ArrayList接口的增删改查方法 
     * 2.理解自动扩容机制 
     *参考:http://blog.csdn.net/u011240877/article/details/52802849 
     */  
    public class MyArrayList<E> {  
        //需要扩容的数组  
        transient Object[] elementData;  
        //数组里的元素个数  
        private int size;  
      
        public boolean add(E o) {  
            /* 
            1.先判断一下,不然会报空指针 
             */  
            if(elementData==null){  
                elementData=new Object[]{};  
                size=0;  
            }  
            /* 
            2.再判断当数组被元素填满时,扩容 
             */  
            if(size==elementData.length){  
                //3.定义一个数组接收原来数组的元素  
                Object[] oldData=elementData;  
                //4.扩容1.5倍  
                int newCapacity=(elementData.length*3)/2;  
                if(newCapacity<size) newCapacity=size;  
                //5.定义一个新长度的数组  
                elementData=new Object[newCapacity];  
                //6.复制  
                System.arraycopy(oldData,0,elementData,0,size);  
            }  
            elementData[size++] = o;  
            return true;  
        }  
      
        public int size(){  
            return size;  
        }  
      
        public E get(int index){  
            return (E) elementData[index];  
        }  
      
        public void clear(){  
            for(int i=0;i<size();i++){  
                elementData[i]=null;  
            }  
            size=0;  
        }  
      
                    /* 
                System提供了一个静态方法arraycopy(),我们可以使用它来实现数组之间的复制。其函数原型是: 
                public static void arraycopy(Object src, 
                                 int srcPos, 
                                 Object dest, 
                                 int destPos, 
                                 int length) 
                src:源数组;    srcPos:源数组要复制的起始位置; 
                dest:目的数组;  destPos:目的数组放置的起始位置;    length:复制的长度。 
                注意:src and dest都必须是同类型或者可以进行转换类型的数组. 
                有趣的是这个函数可以实现自己到自己复制,比如: 
                int[] fun ={0,1,2,3,4,5,6}; 
                System.arraycopy(fun,0,fun,3,3); 
                则结果为:{0,1,2,0,1,2,6}; 
                实现过程是这样的,先生成一个长度为length的临时数组,将fun数组中srcPos 
                到srcPos+length-1之间的数据拷贝到临时数组中,再执行System.arraycopy(临时数组,0,fun,3,3). 
     
                 */  
      
    }  

 

 注意:elementData是用transient修饰的

先说一下:

transient关键字:一个对象中有些属性不需要被默认序列化,可以用transient关键子修饰。

transient修饰的元素,该元素不会进行jvm默认的序列化。也可以自己完成这个元素的序列化
有两个方法签名可以实现。可以参考ArrayList里的两个方法 :
序列化方法:writeObject(java.io.ObjectOutputStream s),
反序列化方法:readObject(java.io.ObjectInputStream s)

arrayList中的elementData 为什么被这个关键字修饰呢?难道不需要这个属性序列化吗?

 其实是这样的,一个arrayList的容量一般是比它的size要大的,比方我的容量是10,但的存进去的值就只有3,也就是size()只有3.
那如果elementData 不被transient修饰的话,就相当于整个容量为10list全部被序列化了,
那我们知道其实list里面就只有3个有效值,其它都是空的,这样会造成资源浪费。
那怎么做呢?transient就发挥作用了,那个变量修饰为transient,使其不能被序列化。


那有的人会问,那不是那三个有效值也不能序列化了。不是的,arrayList提供了一个方法writeObject

源码:

 

private void writeObject(java.io.ObjectOutputStream s)
        throws java.io.IOException{
        // Write out element count, and any hidden stuff
        int expectedModCount = modCount;
        s.defaultWriteObject();

        // Write out size as capacity for behavioural compatibility with clone()
        s.writeInt(size);

        // Write out all elements in the proper order.
        for (int i=0; i<size; i++) {
            s.writeObject(elementData[i]);
        }

        if (modCount != expectedModCount) {
            throw new ConcurrentModificationException();
        }
    }

 

源码分析:

 

 s.defaultWriteObject();        // 默认的属性进行了序列化
 // Write out all elements in the proper order.
        for (int i=0; i<size; i++) {
            s.writeObject(elementData[i]);
        }

//只有transient修饰的元素才进行了序列化,空的没有序列化

参考博客:http://blog.csdn.net/qq_18416057/article/details/73136936?locationNum=10&fps=1

如果对序列化和反序列化有疑问,可以看我另一篇博客,对象的序列化和反序列化:http://www.cnblogs.com/inspred/p/7552690.html







 

posted @ 2017-09-19 14:54  inspire0x001  阅读(324)  评论(0编辑  收藏  举报