JAVA集合之Arraylist使用方法
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JAVA集合之Arraylist使用方法相关的知识,希望对你有一定的参考价值。
Java的集合的集成体系如下
ArrayList实现List接口,具有有序和线程不安全,高效的特点(相比vector)。
1.ArrayList的常用方法
public class ArrayLists
public static void main(String[] args)
//ArrayList的装箱
ArrayList arrayList=new ArrayList();
arrayList.add(1);
arrayList.add(true);
arrayList.add("tom");
System.out.println(arrayList);
//按索引的顺序移除
arrayList.remove(0);
//遍历输出arraylist
System.out.println(arrayList);
//查看是否含有tom
System.out.println(arrayList.contains("tom"));
System.out.println(arrayList);
//查看是否为空
System.out.println(arrayList.isEmpty());
//清除list
//arrayList.clear();
System.out.println(arrayList);
ArrayList arrayList1=new ArrayList();
//arrayList1.add(1);
arrayList1.add(true);
arrayList1.add("tom");
//查看arraylist是否包含arrylist1的全部元素
System.out.println(arrayList.containsAll((arrayList1)));
//删除arraylist包含arrylist1的全部元素
System.out.println(arrayList.removeAll(arrayList1));
System.out.println(arrayList);
二 ArrayList源码解读
ArrayList的扩容机制
ArrayList的初始化的长度大小为10,每次添加前判断是否还有空间,若不足,则扩充为当前容量的1.5倍,使用debug代码,将断点打在ArrayList
public class ArraylistSourceCode
public static void main(String[] args)
ArrayList list=new ArrayList();
list.add("张");
list.add("王");
list.add("周");
list.add("李");
list.add("张");
list.add("王");
list.add("周");
list.add("李");
list.add("张");
list.add("王");
list.add("周");
list.add("李");
//ArrayList维护一个Object数组,modcount计数,初始化定义数组长度为10
public ArrayList()
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
//计数+1
private void ensureExplicitCapacity(int minCapacity)
modCount++;
// 如果队列的容量小于 minCapacity是队列的当前的数量
//判断是否越界
if (minCapacity - elementData.length > 0)
//增加空间
grow(minCapacity);
/**
*arraylist第一次插入数据和空间不足都会执行此方法
* */
private void grow(int minCapacity)
// overflow-conscious code
int oldCapacity = elementData.length;
//容量直接扩为1.5倍
//>>表示右移一位 /2
//<<表示左移一位 *二
int newCapacity = oldCapacity + (oldCapacity >> 1);
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线程不安全以及解决办法
public class ListTest
public static void main(String[] args)
//这是个普通list集合添加的操作,如果不加限制,在多线程的环境下会出现 java.util.ConcurrentModificationException
List<String> alist = new ArrayList<>();
for(int i=0;i<=10;i++)
new Thread(()->
alist.add(UUID.randomUUID().toString().substring(0,5));
System.out.println(alist);
).start();
官方说法是不允许一个线程在修改集合时,另外的线程对其遍读,否则会抛出异常
//修改的方法如下,使用vector,vector线程安全如果排除contains方法和remove方法不具有原子性的话,因为集合添加会有这个问题
List<String> alist = new Vector<>(); //jdk1.0的东西
for(int i=0;i<=10;i++)
new Thread(()->
alist.add(UUID.randomUUID().toString().substring(0,5));
System.out.println(alist);
).start();
没有问题
//使用synchonrizedlist
List<String> alist = Collections.synchronizedList(new ArrayList<>()); //一般的解决方法
for(int i=0;i<=10;i++)
new Thread(()->
alist.add(UUID.randomUUID().toString().substring(0,5));
System.out.println(alist);
).start();
可以实现
//synchronizedList的源码如下 ==》都添加synchonrized
//除了遍历的listIterator方法需要编程人员添加synchonrized
static class SynchronizedList<E>
extends SynchronizedCollection<E>
implements List<E>
private static final long serialVersionUID = -7754090372962971524L;
final List<E> list;
SynchronizedList(List<E> list)
super(list);
this.list = list;
SynchronizedList(List<E> list, Object mutex)
super(list, mutex);
this.list = list;
public boolean equals(Object o)
if (this == o)
return true;
synchronized (mutex) return list.equals(o);
public int hashCode()
synchronized (mutex) return list.hashCode();
public E get(int index)
synchronized (mutex) return list.get(index);
public E set(int index, E element)
synchronized (mutex) return list.set(index, element);
public void add(int index, E element)
synchronized (mutex) list.add(index, element);
public E remove(int index)
synchronized (mutex) return list.remove(index);
public int indexOf(Object o)
synchronized (mutex) return list.indexOf(o);
public int lastIndexOf(Object o)
synchronized (mutex) return list.lastIndexOf(o);
public boolean addAll(int index, Collection<? extends E> c)
synchronized (mutex) return list.addAll(index, c);
public ListIterator<E> listIterator()
return list.listIterator(); // Must be manually synched by user
public ListIterator<E> listIterator(int index)
return list.listIterator(index); // Must be manually synched by user
public List<E> subList(int fromIndex, int toIndex)
synchronized (mutex)
return new SynchronizedList<>(list.subList(fromIndex, toIndex),
mutex);
@Override
public void replaceAll(UnaryOperator<E> operator)
synchronized (mutex) list.replaceAll(operator);
@Override
public void sort(Comparator<? super E> c)
synchronized (mutex) list.sort(c);
... ...
终极方案
/*****
* 读写分离的思想
* 添加容器时,复制容器,往容器添加数据后,使容器指向新的容器,简单来说,类似快照,在用快照替代了原始的
* **/
List<String> alist = new CopyOnWriteArrayList<>();
for(int i=0;i<=10;i++)
new Thread(()->
alist.add(UUID.randomUUID().toString().substring(0,5));
System.out.println(alist);
).start();
参考链接
ConcurrentModificationException
以上是关于JAVA集合之Arraylist使用方法的主要内容,如果未能解决你的问题,请参考以下文章