欢迎来到皮皮网网首页

【老马源码】【街舞小程序源码】【筹码互换指标源码】arraylist源码解读

来源:android源码爆红 时间:2024-11-25 02:59:55

1.ArrayList详解及扩容源码分析
2.arraylist为什么线程不安全
3.Java里面elementData 和elementDats有什么区别吗?

arraylist源码解读

ArrayList详解及扩容源码分析

       在集合框架中,码解ArrayList作为普通类实现List接口,码解如下图所示。码解

       它实现了RandomAccess接口,码解表明支持随机访问;Cloneable接口,码解表明可以实现克隆;Serializable接口,码解老马源码表明支持序列化。码解

       与其他类不同,码解如Vector,码解ArrayList在单线程环境下的码解线程安全性较差,但适用于多线程环境下的码解Vector或CopyOnWriteArrayList。

       ArrayList底层基于连续的码解空间实现,为动态可扩展的码解街舞小程序源码顺序表。

       一、码解构造方法解析

       使用ArrayList(Collection c)构造方法时,码解传入类型必须为E或其子类。

       二、扩容分析

       不带参数的构造方法初始容量为,此时底层数组为空,筹码互换指标源码即`DEFAULT_CAPACITY_EMPTY_ELEMENTDATA`长度为0。

       元素添加时,默认插入数组末尾,调用`ensureCapacityInternal(size + 1)`增加容量。

       若当前容量无法满足增加需求,计算新的广东到香港源码容量以达到所需规模,确保添加元素成功并避免频繁扩容。

       三、常用方法

       通过List.subList(int fromIndex, int toIndex)方法获取子列表,修改原列表元素亦会改变此子列表。

       四、遍历方式

       ArrayList提供for循环、vue源码是多少foreach循环、迭代器三种遍历方法。

       五、缺陷与替代方案

       ArrayList基于数组实现,插入或删除元素导致频繁元素移动,时间复杂度高。在需要任意位置频繁操作的场景下,性能不佳。

       因此,在Java集合中引入了更适合频繁插入和删除操作的LinkedList类。

       版权声明:本文内容基于阿里云实名注册用户的贡献,遵循相关协议规定,包括用户服务协议和知识产权保护指引。发现抄袭内容,可通过侵权投诉表单举报,确保社区内容健康、合规。

arraylist为什么线程不安全

       é¦–先说一下什么是线程不安全:线程安全就是多线程访问时,采用了加锁机制,当一个线程访问该类的某个数据时,进行保护,其他线程不能进行访问直到该线程读取完,其他线程才可使用。不会出现数据不一致或者数据污染。线程不安全就是不提供数据访问保护,有可能出现多个线程先后更改数据造成所得到的数据是脏数据。 如图,List接口下面有两个实现,一个是ArrayList,另外一个是vector。 从源码的角度来看,因为Vector的方法前加了,synchronized 关键字,也就是同步的意思,sun公司希望Vector是线程安全的,而希望arraylist是高效的,缺点就是另外的优点。 说下原理(百度的,很好理解): 一个 ArrayList ,在添加一个元素的时候,它可能会有两步来完成:

       1. 在 Items[Size] 的位置存放此元素;

       2. 增大 Size 的值。

       åœ¨å•çº¿ç¨‹è¿è¡Œçš„情况下,如果 Size = 0,添加一个元素后,此元素在位置 0,而且 Size=1;

       è€Œå¦‚果是在多线程情况下,比如有两个线程,线程 A 先将元素存放在位置 0。但是此时 CPU 调度线程A暂停,线程 B 得到运行的机会。线程B也向此 ArrayList 添加元素,因为此时 Size 仍然等于 0 (注意哦,我们假设的是添加一个元素是要两个步骤哦,而线程A仅仅完成了步骤1),所以线程B也将元素存放在位置0。然后线程A和线程B都继续运行,都增加 Size 的值。

       é‚£å¥½ï¼ŒçŽ°åœ¨æˆ‘们来看看 ArrayList 的情况,元素实际上只有一个,存放在位置 0,而 Size 却等于 2。这就是“线程不安全”了。

       ç¤ºä¾‹ç¨‹åºï¼š

       package test;

       import java.util.ArrayList;

       import java.util.List;

       public class ArrayListInThread implements Runnable {

       List<String> list1 = new ArrayList<String>();// not thread safe

       // List<String> list1 = Collections.synchronizedList(new ArrayList<String>());// thread safe

       public void run() {

       try {

       Thread.sleep((int)(Math.random() * 2));

       }

       catch (InterruptedException e) {

       e.printStackTrace();

       }

       list1.add(Thread.currentThread().getName());

       }

       public static void main(String[] args) throws InterruptedException {

       ThreadGroup group = new ThreadGroup("mygroup");

       ArrayListInThread t = new ArrayListInThread();

       for (int i = 0; i < ; i++) {

       Thread th = new Thread(group, t, String.valueOf(i));

       th.start();

       }

       while (group.activeCount() > 0) {

       Thread.sleep();

       }

       System.out.println();

       System.out.println(t.list1.size()); // it should be if thread safe collection is used.

       }

       }

Java里面elementData 和elementDats有什么区别吗?

       直接看源码,可以看到的是,ArrayList有三个构造函数:

       无参构造:

       无参构造时,Obeject数组elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;

       当其为有参构造时:会有两种情况:

       给定初始容量构造:

       源码具体逻辑如下:

       当 传入的初始容量initialCapacity > 0为真时,创建一个大小为initialCapacity的空数组,并将引用赋给elementData;

       当 传入的初始容量initialCapacity = 0为真时,将空数组EMPTY_ELEMENTDATA赋给elementData;

       当 传入的初始容量initialCapacity < 0为真时,直接抛出IllegalArgumentException异常。