ArrayList实现

数组实现父类:AbstractList接口:List,RandomAccess,Cloneable,Serializable字段://默认容量private static final int DEFAULT_CAPACITY = 10;//空的数组,构造函数参数为0和trim中使用,构造参数给0的人绝对会被打死,每放一个元素,就要重新copy一次private static final Object[] EMPTY_ELEMENTDATA = {};

//实际保存数组,transient,这个字段不用写入流transient Object[] elementData//实际元素数目private int size;
 public ArrayList(int initialCapacity)
{
        if (initialCapacity > 0)
       {
            this.elementData = new Object[initialCapacity];
        }
        else if (initialCapacity == 0)
        {
          //注意初始容量为0时给的对象,EMPTY_ELEMENTDATA
            this.elementData = EMPTY_ELEMENTDATA;
        }
         else
         {
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        }
 }

 public ArrayList()
 {
          //默认构造函数
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
 }

 public ArrayList(Collection<? extends E> c)
{
       //转入的集合转换为数组
        elementData = c.toArray();
      //改变自己的size
        if ((size = elementData.length) != 0)
       {
           //这里有个坑,可能不能正确的返回Object[] Class对象,不能的话复制
            // c.toArray might (incorrectly) not return Object[] (see 6260652)
            if (elementData.getClass() != Object[].class)
                elementData = Arrays.copyOf(elementData, size, Object[].class);
        } else
        {
            // replace with empty array.
            this.elementData = EMPTY_ELEMENTDATA;
        }
  }

//截断,在原数组上移动
public void trimToSize()
{
        modCount++;
        if (size < elementData.length)
       {
            elementData = (size == 0)
              ? EMPTY_ELEMENTDATA
              : Arrays.copyOf(elementData, size);
        }
 }

//比较关心的几个方法,存放,取出,查找
//查找,运行时间上界O(n),从这里也可用看出是允许放null
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;
  }

//反向查找
 public int lastIndexOf(Object o)
{
        if (o == null)
         {
            for (int i = size-1; i >= 0; i--)
                if (elementData[i]==null)
                    return i;
        } else
        {
            for (int i = size-1; i >= 0; i--)
                if (o.equals(elementData[i]))
                    return i;
        }
        return -1;
 }
//返回index位置的元素
E elementData(int index)
{
        return (E) elementData[index];
 }

//获取对应位置元素,O(1)
 public E get(int index)
{
       //检查size,并没有判断小于0
        rangeCheck(index);
        return elementData(index);
}

//将元素放在对应位置,index<size,list当成数组使用,注意,这样的代码会报错
//List<String> list = new ArrayList<>(100);
//		list.set(10, "123");
//根据构造函数可以知道,已经开辟了100长度的数组,但是就是不让你用
 public E set(int index, E element)
{
        rangeCheck(index);
        E oldValue = elementData(index);
        elementData[index] = element;
        return oldValue;
}

private void grow(int minCapacity)
{
        // overflow-conscious code
        int oldCapacity = elementData.length;
        //原来的1.5备长度
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        // minCapacity is usually close to size, so this is a win:
       //注意是新开辟一个数组给elementData
        elementData = Arrays.copyOf(elementData, newCapacity);
 }

 private void ensureExplicitCapacity(int minCapacity)
{
        modCount++;

        // overflow-conscious code
        //1-0,进入if,进行内存复制,开辟新的数组
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
}

private void ensureCapacityInternal(int minCapacity)
{
       //构造函数给0,这里是false
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
        {
            minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
        }

        //ensureExplicitCapacity(1);
        ensureExplicitCapacity(minCapacity);
 }

//增加一个元素
 public boolean add(E e)
 {
       //为什么构造函数给0会被打死,看下面这个函数,一来就要新数组,新的数组长度也只有1
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
 }

//元素放到index位置,0<=index<size
public void add(int index, E element)
{
        rangeCheckForAdd(index);

        ensureCapacityInternal(size + 1);  // Increments modCount!!
        System.arraycopy(elementData, index, elementData, index + 1,
                         size - index);
        elementData[index] = element;
        size++;
}
//移除
 public E remove(int index)
{
        rangeCheck(index);

        modCount++;
        E oldValue = elementData(index);

        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

        return oldValue;
}
//O(n)的移除,注意在fastRemove方法里面也会出现内存复制
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;
 }

//为什么elementData不用置null,方便重用
public void clear()
{
        modCount++;
        // clear to let GC do its work
        for (int i = 0; i < size; i++)
            elementData[i] = null;
        size = 0;
 }

//浅克隆
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);
        }
  }

//返回副本
 public Object[] toArray()
{
        return Arrays.copyOf(elementData, size);
}

结尾附上一个内存分布的代码,有指针真好
int main(int argc, char* argv[])
{
	//int ba[4];
	int a[] = { 1, 2, 3, 4 };
	int c = 5;
	int d = 6;
	int dd = 7;
	cout << a << endl;
	cout << a[-1] << endl;
	cout << a-1 << endl;
	cout<<&dd<<endl;
	cout << &d << endl;
	cout << &c << endl;
	//memcpy(ba, a, sizeof(int) * 4);
	//cout << ba[0] << endl;
	//cout << ba[1] << endl;
	return 0;
}

  

时间: 2024-08-02 07:03:21

ArrayList实现的相关文章

ArrayList以及Map小练

ArrayList常用方法 public static void main(String[] args) { List list = new ArrayList(); List list1 = new ArrayList(); for (int i = 0; i < 5; i++) { list.add(i, "string"+i);//add(E e)向某集合的尾部追加 list1.add(i, "string"+(i+10)); } List list2

java持有对象【2】ArrayList容器续解

此为JDK API1.6.0对ArrayList的解释. ArrayList 使用java泛型创建类很复杂,但是应用预定义的泛型很简单.例如,要想定义用来保存Apple对象的ArrayList,可以声明ArrayList<Apple>,尖括号内为类型参数,(可以为多个).它指定了容器可以保存的类型. 通过使用泛型,可以在编译期防止将错误类型的对象放置到容器中. ArrayList向上转型为List. 应该注意到,在将元素从List中取出时,类型转换不是必须的了.因为List在调用get()时会

手动添加arraylist注解类(Contact联系人对象)

因为在Java核心库不支持arraylist xml直接注解,这里可以自己写个小工具类 Contact.java: package com.newer.xml; import java.util.ArrayList; import org.simpleframework.xml.Attribute; import org.simpleframework.xml.Element; import org.simpleframework.xml.ElementList; import org.simp

Java中ArrayList和LinkedList区别

一般大家都知道ArrayList和LinkedList的大致区别:      1.ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构.      2.对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针.      3.对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据. ArrayList和LinkedList是两个集合类,用于存储一系列的对象引用

ArrayList、string、string[]之间的转换

1.ArrarList 转换为 string[] : ArrayList list = new ArrayList(); list.Add("aaa"); list.Add("bbb"); string[] arrString = (string[])list.ToArray(typeof( string)) ; 2.string[] 转换为 ArrarList : ArrayList list = new ArrayList(new string[] { &quo

ArrayList&amp;LinkedList&amp;Map&amp;Arrays

Java集合框架 1:集合接口 1.1:Collection接口 Collection接口是构造集合框架的基础.它声明所有类集合都将拥有的核心方法 Boolean add(Object obj) 将obj加入到调用类集合中,加入返回true 否则 返回 false Boolean addAll(Collection c) 将c中所有元素都加入到类集合中,都加入返回true否则 false Void clean() 从调用类集合中删除所有元素 Boolean contains(Object obj

ArrayList代码示例

package com.shushine.framework.第七章Java标准类库; import java.util.ArrayList; /** * * <p> * 描述该类情况 {@link 代表跟谁有关系} * </p> * * @author 王超 * @since 1.0 * @date 2016年10月24日 下午7:46:28 * @see 新建|修改|放弃 * @see com.shushine.framework.第七章Java标准类库.ArrayListDe

蓝鸥Unity开发基础二——课时22 ArrayList

一.ArrayList 集合:集合是种容器,在程序中,使用集合管理相关对象组 集合分为非泛型集合和泛型集合 推荐视频讲师博客:http://11165165.blog.51cto.com/ 二.非泛型集合:使用非泛型集合需要引起命名空间System.Collections ArrayList--可以根据需要动态增加的数组 Hashtable--用来存储键值对的哈希表 Queue--遵循先进先出的对列 Stack--遵循后进先出的栈 三.泛型集合:使用泛型集合需要引入命名空间System.Coll

1.21 ArrayList 用法练习。

import java.util.ArrayList; public class TestArrayList { public static void main(String[] args) { //练习 ArrayList add(对象) set(索引) size() 以及构造方法 ArrayList<> String a = "好好学习"; //定义插入的字符串 String b = "天天向上"; ArrayList<String> a

java的List接口的实现类 ArrayList,LinkedList,Vector 的区别

Java的List接口有3个实现类,分别是ArrayList.LinkedList.Vector,他们用于存放多个元素,维护元素的次序,而且允许元素重复. 3个具体实现类的区别如下: 1. ArrayList是最常用的List实现类,内部是通过数组实现的,它允许对元素进行快速随机访问.数组的缺点是每个元素之间不能有间隔,当数组大小不满足时需要增加存储能力,就要将已经有数组的数据复制到新的存储空间中.当从ArrayList的中间位置插入或者删除元素时,需要对数组进行复制.移动.代价比较高.因此,它