Bootstrap

Java ArrayList类(集合)

ArrayList的底层是一个数组;
ArrayList类和数组的区别是:ArrayList类数组的长度是可以变化的,而且ArrayList是一个泛型容器;同时ArrayList中只能存储引用类型,而不能存储基本类型;ArrayList类继承至List接口;
原因是:ArrayList数组中存放的是地址。
ArrayList容器的初始大小为10;
ArrayList的特点

1.查找速度快;
2.增删速度慢;
1. 创建集合对象:ArrayList<String> a = new ArrayList<>(); //右边的<>内可以不写类型;
2. 在对象中添加数据:a.add("list");
3. 在ArrayList中添加一个ArrayList对象:a.addAll(new ArrayList<Integer>(1,2,3,4));
4. 根据索引获取元素:String  name = a.get(3);获取第三个位置的元素;
5. 从集合中删除元素:String name = a.remove(4); 从集合中删除第4位的元素;返回值为被删除的元素;
6. 修改元素的值:String name = a.set(2,"A"); 用于替换元素,返回的是被替换的元素;
7. 用于获取数组的尺度:int length = a.size(); 

如果希望向集合ArrayList当中存储基本数据类型,必须使用基本类型对应的包装类(就是把基本类型转换为引用类型,位于java.lang包下);

ArrayList的线程不安全问题:

1.输出值为null;
elementData[size++] = e;
可以分为两步执行:
1.elementData[size] = e;
2.size++;
当线程1再执行完第一步时,时间片结束,然后线程2执行第一步,此时线程2操作的内存空间和线程1的相同;然后线程1和线程2都执行了一次size++;所以就会导致一个位置被重复执行两次(覆盖的问题),而一个位置没被赋值,为null;

2.数组越界异常;

3.某些线程没有输出值;

ArrayList是线程不安全的:

在多线程的情况下会出现java.util.ConcurrentModificationException的故障;
解决方案:
1.List<String> arr = new ArrayList<>();
  List<String> arr1 = Collections.synchronizedList(arr); //加一个同步机制;
2.使用vector容器;
3.使用Java.util.concurrent.CopyOnWriteArrayList;
写时复制:采用了读写分离的思想;也就是在写的时候加锁(再新开辟的内存上加的锁),然后开辟一块新的内存,在新的内存中写入数据,写完之后,用新的内存代替旧的内存;(好处是:在新的内存中写数据,所以其他线程要读数据的话,可以在旧的内存中读取,这样写的时候也可以读,索引被称为读写分离);
代码:
    public boolean add(E e) {
        synchronized(this.lock) {
            Object[] es = this.getArray();
            int len = es.length;
            es = Arrays.copyOf(es, len + 1);
            es[len] = e;
            this.setArray(es);
            return true;
        }
    }

ArrayList扩容的问题:

正常境况下,ArrayList初始容量为10,每次扩容1.5倍;扩容的方式为:
int newCapacity = oldCapacity + (oldCapacity >> 1);

悦读

道可道,非常道;名可名,非常名。 无名,天地之始,有名,万物之母。 故常无欲,以观其妙,常有欲,以观其徼。 此两者,同出而异名,同谓之玄,玄之又玄,众妙之门。

;