Java集合框架:ArrayList扩容机制解释

标签: java 集合 arrayList
7人阅读 评论(0) 收藏 举报
分类:

1、java中ArrayList该类的定义

public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
    private static final long serialVersionUID = 8683452581122892189L;

    /**
     * 默认容量为10
     */
    private static final int DEFAULT_CAPACITY = 10;

    /**
     * 空数组:用于调用带有容量切容量为0时初始化elementData这个值
     */
    private static final Object[] EMPTY_ELEMENTDATA = {};

    /**
     * 空数组:用于调用空构造时初始化elementData这个值

     */
    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

    /**
     *数组变量
     */
    transient Object[] elementData; // non-private to simplify nested class access

    /**
     * arrayList的长度
     */
    private int size;
   //后面自己需要看源码
   ...
}

2、ArrayList描述

    ArrayList是一个继承abstractList和实现List的接口的实现类。
    ArrayList是以数组实现的数组队列,允许重复。可以通过ArrayList来进行增加,删除,修改,遍历等操作。
    ArrayList可以说是一个动态数组。动态的最好例子可以说就是ArrayList的底层是数组,该数组的长度可以根据实际需要不断增加。

3、ArrayList的扩容机制

    3.1 对外提供的检查是否需要扩容方法

public void ensureCapacity(int minCapacity) {
//判断elementData是否是默认空数组,如果不是minExpand为0,如果是minExpand=DEFAULT_CAPACITY=10
        int minExpand = (elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA)? 0: DEFAULT_CAPACITY;
//如果我们预测的值比数组elementData数组的长度实际要大,需要扩容。只能说明我们需要更大容器的列表。
        if (minCapacity > minExpand) {
            ensureExplicitCapacity(minCapacity);
        }
    }


3.2 内部实现的扩容机制

private void ensureExplicitCapacity(int minCapacity) {
        modCount++;//父类AbstractLisy生命的属性

        // overflow-conscious code
        if (minCapacity - elementData.length > 0)//我们需要的长度比elementData的长度大,扩容
            grow(minCapacity);
}
 private void grow(int minCapacity) {
	// overflow-conscious code
	int oldCapacity = elementData.length;//获取当前存放数据数组的长度
	int newCapacity = oldCapacity + (oldCapacity >> 1);//扩容到原来数组长度的1.5倍
	if (newCapacity - minCapacity < 0)//如果扩容到长度的1.5倍以后,仍然不够用,直接将我们预计的值作为扩容长度
		newCapacity = minCapacity;
	if (newCapacity - MAX_ARRAY_SIZE > 0)//扩容上限最大值为Integer的最大值-8,如果超过这个最大值,使用下面的方法
		newCapacity = hugeCapacity(minCapacity); // minCapacity is usually close to size, so this is a win: 
	elementData = Arrays.copyOf(elementData, newCapacity);//使用数组Arrays的copyOf()进行扩容,每次扩容都采用System.arrayCopy()复制到新数组的 
}
private static int hugeCapacity(int minCapacity) {//如果扩容超过Integer.MAX_VALUE-8,代码会走该方法 
	if (minCapacity < 0) // overflow throw new OutOfMemoryError(); 
	//如果我们预测的长度比Integer.MAX_VALUE-8大,最后取Integer.MAX_VALUE。 
	return (minCapacity > MAX_ARRAY_SIZE) ?Integer.MAX_VALUE : MAX_ARRAY_SIZE; 
}

4、ArrayList遍历方式

                List<String> testList = new ArrayList<String>();
		testList.add("11");
		testList.add("21");
		testList.add("31");
		testList.add("41");
		testList.add("51");
		testList.add("61");
		testList.add("71");
		/**
		 * for循环遍历
		 */
		for(int index=0;index<testList.size();index++){
			System.out.println(testList.get(index));
		}
		System.err.println("===========foreach===========");
		/**
		 * foreach遍历
		 */
		for(String index:testList){
			System.out.println(index);
		}
		System.err.println("===========Iterator===========");
		/**
		 * 迭代器Iterator
		 */
		Iterator<String> iterator = testList.iterator();
		while(iterator.hasNext()){
			System.err.println(iterator.next());
		}
		

5、ArrayList和vector比较

普及:什么是线程安全什么是线程不安全

   线程安全就是多线程访问时,采用了加锁机制,当一个线程访问该类的某个数据时,进行保护,其他线程不能进行访问直到该线程读取完,其他线程才可使用。不会出现数据不一致或者数据污染。

    线程不安全就是不提供数据访问保护,有可能出现多个线程先后更改数据造成所得到的数据是脏数据。 如图,List接口下面有两个实现,一个是ArrayList,另外一个是vector。 从源码的角度来看,因为Vector的方法前加了,synchronized 关键字,也就是同步的意思,sun公司希望Vector是线程安全的,而希望arraylist是高效的,缺点就是另外的优点。

1、Vector每次扩容都是请求其大小的2倍空间,而ArrayList是1.5倍

2、Vector还有一个子类Stack





查看评论

HashMap 的扩容机制

HashMap 类中包含3个和扩容相关的常量: static final int DEFAULT_INITIAL_CAPACITY = 1 static final int MAXIMUM_CA...
  • hackeraaa
  • hackeraaa
  • 2016-03-15 11:38:26
  • 2769

Java ArrayList的自动扩容机制

注意: 不同的JDK版本的扩容机制可能有差异 实验环境:JDK1.8 扩容机制: 当向ArrayList中添加元素的时候,ArrayList如果要满足新元素的存储超过ArrayList存...
  • yang1464657625
  • yang1464657625
  • 2017-03-01 16:04:05
  • 3010

ArrayList自动扩容解析

探索ArrayList     ArrayList的列表对象实质上是存储在一个引用型数组里的,有人认为该数组有“自动增长机制”可以自动改变size大小。正式地说,该数组是无法改变 大小的,实际上它只是...
  • huangfan322
  • huangfan322
  • 2016-09-27 23:26:51
  • 8681

ArrayList和Vector区别以及其扩容机制

ArrayList和Vector区别以及其扩容机制 相同点:   1、ArrayList和Vector都是继承了相同的父类和实现了相同的接口     (extends AbstractList im...
  • dietime1943
  • dietime1943
  • 2017-01-09 15:40:24
  • 1152

Java集合——HashMap(四)扩容机制——resize()

HashMap的扩容机制---resize() 虽然在hashmap的原理里面有这段,但是这个单独拿出来讲rehash或者resize()也是极好的。 什么时候扩容:当向容器添加元素的时候,会...
  • u012961566
  • u012961566
  • 2017-06-09 16:29:48
  • 1583

JDK1.8 ArrayList 扩容详解

几个重要的初始化值 存储数组元素的缓冲区 // non-private to simplify nested class access transient Object[] ele...
  • yz972641975
  • yz972641975
  • 2017-11-29 10:43:29
  • 502

java集合框架中的几种扩容方式小结

对于java中的各种集合类,根据底层的具体实现,小结了一下大致有3种扩容的方式: 1、对于以散列表为底层数据结构实现的,(譬如hashset,hashmap,hashtable等),扩容方式为当链表...
  • windy26205
  • windy26205
  • 2012-02-10 00:48:31
  • 2075

ArrayList的自动扩充机制

ArrayList的自动扩充机制
  • xidiancoder
  • xidiancoder
  • 2017-02-12 19:47:46
  • 4203

ArrayList的动态扩容的实现

ArrayList可以实现容量的自适应的增加,通过阅读源代码,对这个机制进行一下简单的分析。 首先,ArrayList有一个初始的默认大小,为10.  private static final i...
  • qfycc92
  • qfycc92
  • 2015-04-29 18:47:39
  • 7168

ArrayList扩容机制

Arraylist是用Object数组实现的,扩容是生成新的数组,不是在原来的数组中扩容 /** * Appends the specified element to the end ...
  • u010002184
  • u010002184
  • 2017-05-27 17:53:44
  • 638
    个人资料
    持之以恒
    等级:
    访问量: 2627
    积分: 212
    排名: 34万+
    文章存档