JAVA集合之Arraylist使用方法

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JAVA集合之Arraylist使用方法相关的知识,希望对你有一定的参考价值。


Java的集合的集成体系如下

JAVA集合之Arraylist使用方法_System


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);



JAVA集合之Arraylist使用方法_List_02

二 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;

JAVA集合之Arraylist使用方法_ci_03

//计数+1
private void ensureExplicitCapacity(int minCapacity)
modCount++;
// 如果队列的容量小于 minCapacity是队列的当前的数量
//判断是否越界
if (minCapacity - elementData.length > 0)
//增加空间
grow(minCapacity);

JAVA集合之Arraylist使用方法_ci_04

/**
*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);

JAVA集合之Arraylist使用方法_System_05

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();


JAVA集合之Arraylist使用方法_System_06


官方说法是不允许一个线程在修改集合时,另外的线程对其遍读,否则会抛出异常

JAVA集合之Arraylist使用方法_List_07

//修改的方法如下,使用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();

JAVA集合之Arraylist使用方法_List_08


没有问题

//使用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();

JAVA集合之Arraylist使用方法_List_09

参考链接
​​​ConcurrentModificationException​

​CopyOnWriteArrayList​


以上是关于JAVA集合之Arraylist使用方法的主要内容,如果未能解决你的问题,请参考以下文章

JAVA集合之Arraylist使用方法

java集合系列之ArrayList源码分析

JAVA容器之ArrayList集合详解

java之集合ArrayList

深入理解java集合框架之---------Arraylist集合 -----添加方法

深入理解java集合框架之---------Arraylist集合 -----构造函数