你的位置:首页 > Java教程

[Java教程]【学习篇】java


1.ArrayList类
         API文档地址:
http://docs.oracle.com/javase/7/docs/api/  
         翻译过来大致意思(英文非常一般,有错误请大家帮忙指出并纠正,谢谢):通过可变数组实现接口 List 接口。实现所有可选列表的操作,并且运行所有元素都为null. 除了实现接口中的方法外,还提供了一个方法操作数组大小来存储列表中的数组大小。(该类相当于个体,是不同步的,也就是线程不安全)
            size ,isEmpty,get.set.iterator an listIterator 这些操作运行在固定的时间中,add 操作运行在分阶段的固定时间,也就是添加n个元素则需要O(n)的时间。所有其他操作运行时间都是单线程(粗略的讲)。The constant factor is low compared to that for the LinkedList implementation
           所有ArrayList都有一个容量。容量用来存放数组元素列表。容量始终和数组列表一样大小。元素添加到ArrayList中后,容量会自定增长。The details of the growth policy are not specified beyond the fact that adding an element has constant amortized time cost。
            在添加大量元素前,应用程序可以说使用ensureCapacity方法操作增加实例容量,这样可以减少递增式再分配的数量。
             注意,次实现是不同步的。如果多个线程同时访问同一个ArrayList实例,如果其中至少有一个线程修改了列表,那么必须要同外部同步。(修改是指增加 或者添加一个或多个元素,或者调整支持阵列;仅仅修改一个元素的值不是一个结构修改)通常的是通过封装的对象方法来完成。如果不存在这样的对象方法,他应 该使用 
Collections.synchronizedList 方法。最好的做法是在创建时,防止其他非同步访问列表。
    List list = Collections.synchronizedList(new ArrayList(...));
   The iterators returned by this class's iterator and listIterator methods are fail-fast: if the list is structurally modified at any time after the iterator is created, in any way except through the iterator's own remove or add methods, the iterator will throw aConcurrentModificationException. Thus, in the face of concurrent modification, the iterator fails quickly and cleanly, rather than risking arbitrary, non-deterministic behavior at an undetermined time in the future.。
       Note that the fail-fast behavior of an iterator cannot be guaranteed as it is, generally speaking, impossible to make any hard guarantees in the presence of unsynchronized concurrent modification. Fail-fast iterators throw ConcurrentModificationException on a best-effort basis. Therefore, it would be wrong to write a program that depended on this exception for its correctness: the fail-fast behavior of iterators should be used only to detect bugs
          这个类是java集合类中的一员
 
 
          从官方介绍上,我们可以知道大约几点情况:
         1. ArrayList 源码中是通过数组实现(实际上看类名 array 就知道数组了)
         2.添加新元素时,效率会有影响。访问查询迭代操作会比较快速
         3.ArrayList有一个容量值,通过ensureCapacity方法设置这个容量值,来帮助arrayList优化(因为java中数组是固定值,如果arrayList存放的值比较大,我们应该提前告诉arrayList需要多的容量的数组)
         4.ArrayList不是现场安全的,可以用 Collections.synchronizedList 方法帮助同步。
         5.fail-fast  机制

 
 
2.看看ArrayList类
    声明了4个属性如下:
     prviate static final int DEFAULT_CATACITY = 10 ;                 //变量名翻译过来就是   默认容量
     private static final Object[] EMPTY_ELEMENTDATA={};      // 就是一个空的数组
     private transient Object[] elementData;                           //有个数组,这个就是ArrayList存储对象的数组
     private int size;                                                                   //元素的个数
 
    从4个属性上,可以看到 ArrayList 底层是通过数组结构在存放的 elementData
     
     问: 1. 声明属性关键字 transient  有什么用?
             2. 既然有了数组 elementData, 获取长度用 .length 就可以了,为什么要用 size ?
 
3.构造方法:
   不多就3个如下:
   1. 自己给数组长度
  public ArrayList(int initialCapacity) {    super();    if (initialCapacity < 0)      throw new IllegalArgumentException("Illegal Capacity: "+                        initialCapacity);    this.elementData = new Object[initialCapacity];  }


   2. 默认一个空数组
  public ArrayList() {    super();    this.elementData = EMPTY_ELEMENTDATA;  }


    3.给一个Collection到数组中,可以看到,ArrayList通过复制的方式,把Collection复制到elementData中
  public ArrayList(Collection<? extends E> c) {    elementData = c.toArray();    size = elementData.length;    // c.toArray might (incorrectly) not return Object[] (see 6260652)    if (elementData.getClass() != Object[].class)      elementData = Arrays.copyOf(elementData, size, Object[].class);  }

 


 
4.操作方法:
   操作方法有:  add(E e) ,add(int index,E element), addAll(Collection<? extends E> c),addAll(int index,Collection<? extends E> c)  等等,大家可以看看源码由于主要说明ArrayList是在操作数组,所以这些方法中,只拿其中一个说明下。
 
   1. 添加一个元素方法
  public boolean add(E e) {    ensureCapacityInternal(size + 1); // Increments modCount!!    elementData[size++] = e;    return true;  }


    从方法体中,可以看到分2步操作,1.声明一个数组长度,2.给数组下标赋值。   
 
 
5. ensureCapacity 方法
  public void ensureCapacity(int minCapacity) {    // 判断是否一个 空数组,如果是返回 DEFAULT_CAPACITY ,主要就是告诉你,别犯贱在ArrayList声明还没使用的情况下就设置一个小于默认值的容量进来。    int minExpand = (elementData != EMPTY_ELEMENTDATA)      // any size if real element table      ? 0      // larger than default for empty table. It's already supposed to be      // at default size.      : DEFAULT_CAPACITY;    if (minCapacity > minExpand) {      ensureExplicitCapacity(minCapacity);    }  }    


  这个方法在ArrayList的容量中已经有元素的情况下可以使用,一般都是在不断有大量 Collection 进来的时候用,因为提前告诉系统要一个很大的数组装元素,不要不断的创建新数组,复制消耗性能。
 
6.trimToSize 方法:
  public void trimToSize() {    modCount++;    if (size < elementData.length) {      elementData = Arrays.copyOf(elementData, size);    }  }


 ArrayList还给我们提供了将底层数组的容量调整为当前列表保存的实际元素的大小的功能。它可以通过trimToSize方法来实现
 

7.Fail-Fast机制:

待续中...