newArrayListWithExpectedSize()和newArrayListWithCapacity()详细对比

package com.lxk.guavaTest;
 
import com.google.common.collect.Lists;
 
import java.util.List;
 
/**
 * Created by lxk on 2016/11/7
 */
public class ListsTest {
 
    public static void main(String[] args) {
        testLists();
    }
 
    /**
     * 测试 guava Lists
     */
    private static void testLists() {
 
        List<String> list1 = Lists.newArrayList();
        for (int i = 0; i < 10; i++) {
            list1.add(i + "");
        }
        System.out.println("list1: " + list1);
        List<String> list2 = Lists.newArrayList("1", "2", "3");
        System.out.println("list2: " + list2);
        List<String> list3 = Lists.newArrayList(new String[]{"22", "22"});
        System.out.println("list3: " + list3);
        List<String> list4 = Lists.newArrayList(list1);
        System.out.println("list4: " + list4);
 
        //下面的这个写法呢是在初始化list的时候,说明容器的扩容界限值
 
        //使用条件:你确定你的容器会装多少个,不确定就用一般形式的
 
        //说明:这个容器超过10个还是会自动扩容的。不用担心容量不够用。默认是分配一个容量为10的数组,不够将扩容
        //执行数组数据迁移操作:新建新数组,复制就数组数据到新数组(包括开辟新空间,copy数据等等,耗时,耗性能)
 
        //对下数字10的说明:若直接new一个list的话,默认大小是10的数组,下面的方式则是 5L + x + x/10 = 16L(x = 10),在17的时候扩容
 
        //整个来说的优点有:节约内存,节约时间,节约性能。代码质量提高。
        List<String> list = Lists.newArrayListWithExpectedSize(10);
 
        //这个方法就是直接返回一个10的数组。
        List<String> list_ = Lists.newArrayListWithCapacity(10);
    }
}


下面先是关于Lists.newArrayListWithExpectedSize(10)的源码简单分析
  @GwtCompatible(serializable = true)
  public static <E> ArrayList<E> newArrayListWithExpectedSize(int estimatedSize) {
    return new ArrayList<E>(computeArrayListCapacity(estimatedSize));
  }
    
  static int computeArrayListCapacity(int arraySize) {
    checkNonnegative(arraySize, "arraySize");
 
    // TODO(kevinb): Figure out the right behavior, and document it
    return Ints.saturatedCast(5L + arraySize + (arraySize / 10));
  }
  static int checkNonnegative(int value, String name) {
    if (value < 0) {
      throw new IllegalArgumentException(name + " cannot be negative but was: " + value);
    }
    return value;
  }
  public static int saturatedCast(long value) {
    if (value > Integer.MAX_VALUE) {
      return Integer.MAX_VALUE;
    }
    if (value < Integer.MIN_VALUE) {
      return Integer.MIN_VALUE;
    }
    return (int) value;
  }    
  
    public ArrayList(int initialCapacity) {
        super();
        if (initialCapacity < 0)
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        this.elementData = new Object[initialCapacity];
    }

然后是Lists.newArrayListWithCapacity(10)的源码简单分析
  @GwtCompatible(serializable = true)
  public static <E> ArrayList<E> newArrayListWithCapacity(int initialArraySize) {
    checkNonnegative(initialArraySize, "initialArraySize"); // for GWT.
    return new ArrayList<E>(initialArraySize);
  }

然后看上面的主要是ArrayList,然后就看看ArrayList源码里面的add方法以及如何扩容的。
    /**
     * list底层的用来保存数据的数组
     */
    private transient Object[] elementData;
    /**
     * Shared empty array instance used for empty instances.
     */
    private static final Object[] EMPTY_ELEMENTDATA = {};
    /**
     * Default initial capacity.
     */
    private static final int DEFAULT_CAPACITY = 10;
 
    public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!! (Increments 翻译-- 增量; 增长( increment的名词复数 ); 增额; 定期的加薪;)
        elementData[size++] = e;
        return true;
    }
    private void ensureCapacityInternal(int minCapacity) { // Internal 翻译--  内部的; 国内的; 体内的; 内心的;   Capacity  翻译--  容量; 性能; 才能; 生产能力;
        if (elementData == EMPTY_ELEMENTDATA) {
            minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
        }
 
        ensureExplicitCapacity(minCapacity);
    }
    
    private void ensureExplicitCapacity(int minCapacity) { //Explicit  翻译-- 明确的,清楚的; 直言的; 详述的; 不隐瞒的;
        modCount++;
 
        // overflow-conscious code
        if (minCapacity - elementData.length > 0) // 扩容条件,就是minCapacity = size + 1 大于当前数组的长度。就扩容。
            grow(minCapacity);
    }
    
    private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + (oldCapacity >> 1); //新容量相当于是原来容量的1.5倍(old + old>>1右移一位即除以2)
        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 = Arrays.copyOf(elementData, newCapacity); // 复制旧数组数据到新数组
    }

关于 ArrayList 的modCount属性,java源码里面写的注释很长一大串,不是一时半会可以看的明白的。我就做个记录,翻译一下。
    /**
     * The number of times this list has been <i>structurally modified</i>.  这个list的结构已经被修改过的次数
     * Structural modifications are those that change the size of the        结构修改是那些改变list的size属性,
     * list, or otherwise perturb it in such a fashion that iterations in    或者其他方式如迭代进度可能会产生不正确的结果 
     * progress may yield incorrect results.
     *
     * <p>This field is used by the iterator and list iterator implementation  这个字段是由迭代器和列表迭代器实现的
     * returned by the {@code iterator} and {@code listIterator} methods.      代码迭代器listIterator方法返回的代码
     * If the value of this field changes unexpectedly, the iterator (or list  如果此字段的值意外更改,则迭代器(list迭代器)
     * iterator) will throw a {@code ConcurrentModificationException} in       将在响应迭代器的next方法,remove方法,previous(),set(),add()等方法
     * response to the {@code next}, {@code remove}, {@code previous},         抛出concurrentmodificationexception 异常
     * {@code set} or {@code add} operations.  This provides                   这提供了
     * <i>fail-fast</i> behavior, rather than non-deterministic behavior in    快速失败的行为,而不是在面对迭代过程中,并发修改的非确定性行为
     * the face of concurrent modification during iteration.
     *
     * <p><b>Use of this field by subclasses is optional.</b> If a subclass    子类们使用这个字段是可选的,如果一个子类
     * wishes to provide fail-fast iterators (and list iterators), then it     希望提供快速失败的迭代器(lsit迭代器),那么 它
     * merely has to increment this field in its {@code add(int, E)} and       仅仅需要增加这个字段在他的 add,remove,方法
     * {@code remove(int)} methods (and any other methods that it overrides    (或者其他任何修改了list结构的方法)
     * that result in structural modifications to the list).  A single call to  一个单一的调用
     * {@code add(int, E)} or {@code remove(int)} must add no more than         add()或者remove()方法,必须增加不超过
     * one to this field, or the iterators (and list iterators) will throw      1 的大小的值,给这个字段。否则,迭代器或者list迭代器将抛出
     * bogus {@code ConcurrentModificationExceptions}.  If an implementation    ConcurrentModificationExceptions 异常   如果一个实现
     * does not wish to provide fail-fast iterators, this field may be          不希望提供快速失败迭代器,这个字段可以忽视
     * ignored.                                              
     */

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值