[Java][集合][List系列][ArrayList、Vector及fail-fast机制小结]

1、ArrayList底层使用数组实现的
transient Object[] elementData;
2、默认容量是10,构造时可以指定初始容量,扩展容量时,公式是(ori * 3)/2 + 1,最大容量是Integer.MAX_VALUE - 8
容量是容量,与list.size()元素总量是两回事,list.size()是实际元素的长度
3、大数组时,容量决定着list的内存占用大小
4、 ArrayList进行元素访问,get()方法是最具效率的写法,其实就是数组索引访问
5、fail-fast 机制是java集合(Collection)中的一种错误机制。
当多个线程对同一个集合的内容进行操作时,就可能会产生fail-fast事件。
例如:当某一个线程A通过iterator去遍历某集合的过程中,若该集合的内容被其他线程所改变了;
那么线程A访问集合时,就会抛出ConcurrentModificationException异常,产生fail-fast事件。
简单讲,就是两个线程,拿同一个ArrayList对象,调用它的Iterator()方法,产生了两个ArrayList.Itr对象,
拿去操作list,一个删元素,一个读元素,Itr最终也是操作ArrayList对象,是同一个对象
因此,存在线程同步问题。

但看Itr操作,get()方法,均没见有同步方面的措施
因此,有个疑问,虽然有fail-fast机制,但没有同步,难道就不会说checkModification()方法之后,恰好通过,然后线程1停止,线程2去删除 ,线程1回来继续读取而出错吗?
正解,官方有说明:
注意,迭代器的快速失败行为不能得到保证,一般来说,存在不同步的并发修改时,不可能作出任何硬性保证。快速失败迭代器尽最大努力抛出 ConcurrentModificationException。因此,编写依赖于此异常的程序的方式是错误的,正确做法是:迭代器的快速失败行为应该仅用于检测程序错误。

public void testList(){
    //ArrayList底层使用数组实现的
    //默认容量是10,构造时可以指定初始容量,扩展容量时,公式是(ori * 3)/2 + 1
    //但容量是容量,与list.size()元素总量是两回事
    //大数组时,容量决定着list的内存占用大小
    List<String> list = new ArrayList<>(30);

    //List相关的API如下,重点关注clone(),索引操作特点,对象比较相等条件,序列化
    //        // AbstractCollection中定义的API
    //        void                add(int location, E object)
    //        boolean             addAll(int location, Collection<? extends E> collection)
    //        E                   get(int location)
    //        int                 indexOf(Object object)
    //        int                 lastIndexOf(Object object)
    //        ListIterator<E>     listIterator(int location)
    //        ListIterator<E>     listIterator()
    //        E                   remove(int location)
    //        E                   set(int location, E object)
    //        List<E>             subList(int start, int end)
    //        // ArrayList新增的API
    //        Object               clone()
    //        void                 ensureCapacity(int minimumCapacity)
    //        void                 trimToSize()
    //        void                 removeRange(int fromIndex, int toIndex)

    //基本操作
    for (int i = 0; i < 100; i++) {
        list.add(new Integer(i).toString());
    }

    //元素访问
    //三种方式,fori + get()进行随机访问,iterator,foreach
    //可想而知,fori + get()是最快的,因为底层是数组,通过索引访问最快,O(1)速度
    //因此,ArrayList进行元素访问,get()方法是最具效率的写法
    for (int i = 0; i < 100; i++) {
        System.out.println(list.get(i));
    }

    vectorToArray1(new ArrayList<Integer>(5));
    vectorToArray2(new ArrayList<Integer>(5));
    vectorToArray3(new ArrayList<Integer>(5));

}

// toArray(T[] contents)调用方式一
public static Integer[] vectorToArray1(ArrayList<Integer> v) {
    Integer[] newText = new Integer[v.size()];
    v.toArray(newText);
    return newText;
}

// toArray(T[] contents)调用方式二。最常用!
public static Integer[] vectorToArray2(ArrayList<Integer> v) {
    Integer[] newText = (Integer[])v.toArray(new Integer[0]);
    return newText;
}

// toArray(T[] contents)调用方式三
public static Integer[] vectorToArray3(ArrayList<Integer> v) {
    Integer[] newText = new Integer[v.size()];
    Integer[] newStrings = (Integer[])v.toArray(newText);
    return newStrings;
}

Vector

Vector 是矢量队列,它是JDK1.0版本添加的类。
Vector 继承了AbstractList,实现了List;所以,它是一个队列,支持相关的添加、删除、修改、遍历等功能。
Vector 实现了RandmoAccess接口,即提供了随机访问功能。
和ArrayList不同,Vector中的操作是线程安全的。
但已被抛弃
从 Java 2 平台 v1.2 开始,此类改进为可以实现 List 接口。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值