zoukankan      html  css  js  c++  java
  • 我的集合学习笔记--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







  • 相关阅读:
    海尔U+的启发:让用户对智能家居拥有“话语权”
    关于hash和ico的一些关联
    二维码简单介绍
    卡特兰数 大数模板
    C++ Linux 多线程之创建、管理线程
    Objective-c开发教程--MRC和ARC混编
    APP 打包測试流程 从零開始
    hdu4848 求到达每一个点总时间最短(sum[d[i]])。
    表结构变更后出现的ERROR OGG-01161 Bad column index (88)
    【Linux学习】Ubuntu下内核编译(一)
  • 原文地址:https://www.cnblogs.com/inspred/p/7551853.html
Copyright © 2011-2022 走看看