源码面前,原形毕露之ArrayList源码阅读

来源:互联网 发布:2017年nba新秀数据 编辑:程序博客网 时间:2024/05/22 07:58

1.类的定义:public class ArrayList extends AbstractList
implements List, RandomAccess, Cloneable, java.io.Serializable可以看出,ArrayList可以序列化,使用clone()方法可进行浅层复制。

2.数据成员的声明:

private static final long serialVersionUID = 8683452581122892189L;    /**     * Default initial capacity.     */    private static final int DEFAULT_CAPACITY = 10;    /**     * Shared empty array instance used for empty instances.     */    private static final Object[] EMPTY_ELEMENTDATA = {};    /**     * Shared empty array instance used for default sized empty instances. We     * distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when     * first element is added.     */    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};    /**     * The array buffer into which the elements of the ArrayList are stored.     * The capacity of the ArrayList is the length of this array buffer. Any     * empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA     * will be expanded to DEFAULT_CAPACITY when the first element is added.     */    transient Object[] elementData; // non-private to simplify nested class access    /**     * The size of the ArrayList (the number of elements it contains).     *     * @serial     */    private int size;

看来ArrayList中所有元素都是以Object对象的形式存储的。

3.看一个重要的的函数public boolean contains(Object o),这个函数可以返回ArrayList中是否包含元素o.先看看这个函数的实现:

public boolean contains(Object o) {        return indexOf(o) >= 0;    }public int indexOf(Object o) {        if (o == null) {            for (int i = 0; i < size; i++)                if (elementData[i]==null)                    return i;        } else {            for (int i = 0; i < size; i++)                if (o.equals(elementData[i]))                    return i;        }        return -1;    }

曾经刷过这样一道题:

现有一个小写英文字母组成的字符串s和一个包含较短小写英文字符串的数组p,请设计一个高效算法,对于p中的每一个较短字符串,判断其是否为s的子串。
给定一个string数组p和它的大小n,同时给定string s,为母串,请返回一个bool数组,每个元素代表p中的对应字符串是否为s的子串。保证p中的串长度小于等于8,且p中的串的个数小于等于500,同时保证s的长度小于等于1000.

当时我给出的解答是:

//package com.nowcoder.CodingCrack;import java.util.*;public class Substr {    public boolean[] chkSubStr(String[] p, int n, String s) {        boolean resBool[] = new boolean[p.length];        for (int i = 0;i < p.length;i++)        {            resBool[i] = chkSubStr1(p[i],s);        }        return resBool;        // write code here    }    public boolean chkSubStr1(String pi,String s)    {        if (pi == "")            return false;        if (pi.length() > s.length())            return false;        char piChar [] = pi.toCharArray();        char sChar [] = s.toCharArray();        int indexs = 0;        int indexpi = 0;        while (indexs < s.length())        {            while (indexs < sChar.length && piChar[indexpi] != sChar[indexs])            {                ++indexs;            }            if (indexs == sChar.length && piChar[indexpi] != sChar[indexs - 1])                return false;            while (indexpi < piChar.length && indexs< s.length() && piChar[indexpi] == sChar[indexs] ){                ++indexs;                ++indexpi;            }            if (indexpi == piChar.length && indexs <= sChar.length)                return true;            indexs = indexs - indexpi + 1;            indexpi = 0;        }        return false;       }    }

调试了好久才提交成功,用contains()函数就方便了:

public boolean[] chkSubStr(String[] p, int n, String s) {        boolean[] res = new boolean[n];                for (int i = 0; i < n; i++) {                                res[i] = s.contains(p[i]);        }        }}

4.clone()方法的重写:

 public Object clone() {        try {            ArrayList<?> v = (ArrayList<?>) super.clone();            v.elementData = Arrays.copyOf(elementData, size);            v.modCount = 0;            return v;        } catch (CloneNotSupportedException e) {            // this shouldn't happen, since we are Cloneable            throw new InternalError(e);        }    }

这仅仅是shallow clone,clone()出来的对象和原对象通过Arrays.copyOf()方法拥有相同的elements.

5.public T[] toArray(T[] a) 方法将ArrayList转成数组类型,如

ArrayList<Integer> myList = new ArrayList<Integer>(10);        myList.add(1);        myList.add(2);        myList.add(2);        myList.add(9);        Integer [] testToArr = myList.toArray(new Integer[myList.size()]);        for (int i = 0;i < testToArr.length;i++)            System.out.print(testToArr[i] + " ");

6.ArrayList的get()和set()方法

public E get(int index) {        rangeCheck(index);        return elementData(index);    }public E set(int index, E element) {        rangeCheck(index);        E oldValue = elementData(index);        elementData[index] = element;        return oldValue;    }

要注意的是,set()方法会返回修改之前的值

7.remove()方法

 public boolean remove(Object o) {        if (o == null) {            for (int index = 0; index < size; index++)                if (elementData[index] == null) {                    fastRemove(index);                    return true;                }        } else {            for (int index = 0; index < size; index++)                if (o.equals(elementData[index])) {                    fastRemove(index);                    return true;                }        }        return false;    }private void fastRemove(int index) {        modCount++;        int numMoved = size - index - 1;        if (numMoved > 0)            System.arraycopy(elementData, index+1, elementData, index,                             numMoved);        elementData[--size] = null; // clear to let GC do its work    }
1 0
原创粉丝点击