当前位置:   article > 正文

Java集合:关于ArrayList类_java arraylist包含

java arraylist包含

一、ArrayList的概念

ArrayList 类底层数据结构是动态数组,与普通数组的区别就是它是没有固定大小的限制,我们可以添加或删除元素。

ArrayList 继承了 AbstractList ,并实现了 List 接口。

ArrayLisy不但拥有Collection中的方法,还拥有List中的所有方法

img

特点:

  1. 有序
  2. 可重复
  3. 数据可为null
  4. 查询快

缺点:

​ 1.增删慢

ArrayList 类位于 java.util 包中,使用前需要引入它,语法格式如下:

import java.util.ArrayList; // 引入 ArrayList 类

ArrayList<E> objectName =new ArrayList<>();  // 初始化
  • 1
  • 2
  • 3

二、ArrayList的方法

2.1构造方法

ArrayList中有三种构造方法

  • public ArrayList() 构造一个初始容量为0的空列表。在添加元素的时候,赋予默认容量10。
  • public ArrayList(Collection<? extends E> c) 构造一个包含指定集合的元素的列表,按照它们由集合的迭代器返回的顺序。
  • public ArrayList(int initialCapacity) 构造具有指定初始容量的空

2.2 ArrayList中的常用方法

方法描述
add()将元素插入到指定位置的 arraylist 中
addAll()添加集合中的所有元素到 arraylist 中
clear()删除 arraylist 中的所有元素
clone()复制一份 arraylist
contains()判断元素是否在 arraylist
get()通过索引值获取 arraylist 中的元素
indexOf()返回 arraylist 中元素的索引值
removeAll()删除存在于指定集合中的 arraylist 里的所有元素
remove()删除 arraylist 里的单个元素
size()返回 arraylist 里元素数量
isEmpty()判断 arraylist 是否为空
subList()截取部分 arraylist 的元素
set()替换 arraylist 中指定索引的元素
sort()对 arraylist 元素进行排序
toArray()将 arraylist 转换为数组
toString()将 arraylist 转换为字符串
ensureCapacity设置指定容量大小的 arraylist
lastIndexOf()返回指定元素在 arraylist 中最后一次出现的位置
retainAll()保留 arraylist 中在指定集合中也存在的那些元素
containsAll()查看 arraylist 是否包含指定集合中的所有元素
trimToSize()将 arraylist 中的容量调整为数组中的元素个数
removeRange()删除 arraylist 中指定索引之间存在的元素
replaceAll()将给定的操作内容替换掉数组中每一个元素
removeIf()删除所有满足特定条件的 arraylist 元素
forEach()遍历 arraylist 中每一个元素并执行特定操作

2.3代码演示

import java.util.ArrayList;

public class DemoTest {

    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<String>();
        //添加元素
        list.add("xiaoming");
        list.add("xiaoliang");
        list.add("xiaodu");
        //访问元素
        list.get(0);
        //修改元素
        list.set(0,"xiaozhang");
        //删除元素
        list.remove(0);
        //计算集合大小
        list.size();
        //排序
        Collections.sort(list);//默认升序
        //遍历集合
        for (String str : list) {
            System.out.print(str);//xiaoduxiaoliang
        }

    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

三、ArrayList的动态扩容

3.1ArrayList 源码分析

ArrayList<String> list = new ArrayList<String>();
  • 1

ArrayList主要属性:

// 如果不指定容量(空构造器),则在添加数据时去构造器默认初始容量最小为 10
private static final int DEFAULT_CAPACITY = 10;

// 出现在需要用到空数组的地方,其中一处是使用自定义初始容量构造方法时候如果你指定初始容量为0的时候,那么elementData指向该数组
// 另一处是使用包含指定collection集合元素的列表的构造方法时,如果被包含的列表中没有数据,那么elementData指向该数组
private static final Object[] EMPTY_ELEMENTDATA = {};

// 如果使用默认构造方法,那么elementData指向该数组
// 在添加元素时会判断是否是使用默认构造器第一次添加,如果是数组就会扩容至10个容量
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

// 默认未初始化的储存 ArrayList集合元素的底层数组,其长度就是 ArrayList的容量
transient Object[] elementData;

// 私有的elementData数组中具体的元素对象的数量,可通过size方法获得。默认初始值为0,在add、remove等方法时size会改变
private int size;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

ArrayList构造方法:

// 默认的构造器
public ArrayList() {
	// Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {} 空数组
	this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}

// 自定义容量大小的构造器
public ArrayList(int initialCapacity) {
	if (initialCapacity > 0) {
		this.elementData = new Object[initialCapacity];
	} else if (initialCapacity == 0) {
		this.elementData = EMPTY_ELEMENTDATA;
	} else {
		throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

从上面的构造器中,可以得出以下结论

  • 如果使用 ArrayList 的默认构造器时,它的初始容量就是 0
  • 如果使用 ArrayList 的有参构造器时,它的初始容量就是你传入的参数 initialCapacity的值

根据上面的两个结论,不管是使用默认或有参构造器时,我们可以使其初始容量为 0,那么它的动态扩容发生在哪里?可以肯定就发生在 add() 方法中,那么查看 add() 方法源码如下 :

public boolean add(E e) {
	// ensureCapacityInternal() 如下
	ensureCapacityInternal(size + 1);  // Increments modCount!!
	elementData[size++] = e;
    return true;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

继续深入:

// 1.第一次 add 时,参数 minCapacity = 1
private void ensureCapacityInternal(int minCapacity) {
	ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}

// 2.calculateCapacity() 方法
private static int calculateCapacity(Object[] elementData, int minCapacity) {	
	// 如果是第一次 add 元素
	if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
		// minCapacity 设置为 DEFAULT_CAPACITY 与 minCapacity 的最大值
		return Math.max(DEFAULT_CAPACITY, minCapacity);
	}
    return minCapacity;
}

// 3.ensureExplicitCapacity() 方法
private void ensureExplicitCapacity(int minCapacity) {
        modCount++;

	// overflow-conscious code
	if (minCapacity - elementData.length > 0)
		grow(minCapacity);
}

//4. grow()方法
private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        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);
    }

//5.hugeCapacity()方法
 private static int hugeCapacity(int minCapacity) {
        if (minCapacity < 0) // overflow
            throw new OutOfMemoryError();
        return (minCapacity > MAX_ARRAY_SIZE) ?
            Integer.MAX_VALUE :
            MAX_ARRAY_SIZE;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45

这里的意思就是: 如果是第一次添加元素,就默认一个10大小的容量,然后通过比较集合的大小,决定是否要动态扩容,像第一次添加元素,就不需要扩容,newCapacity=10,然后调用Arrays.copyOf(elementData, newCapacity) 创建一个新的大小为10的数组。

3.2总结

初始容量:

  • 如果使用 ArrayList的默认无参构造器时,它的初始容量就是 0

  • 如果使用 ArrayList的有参构造器时,它的初始容量就是你传入的参数 initialCapacity的值。

add()添加元素:

  • 如果是默认无参构造器创建的集合对象,在第一次添加元素时,会创建一个默认10大小的数组,然后进行添加元素。
  • 如果是有参构造器,就会判断集合的大小跟容量,如果集合大小>容量,就会新建一个1.5倍大小的数据,进行元素拷贝。如果集合大小<容量,就继续添加元素,不进行扩容。
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Guff_9hys/article/detail/766398
推荐阅读
相关标签
  

闽ICP备14008679号