【Java集合-3】ArrayList简析




[]( )1.4 ArrayList的API

---------------------------------------------------------------------------



| 返回值 | 方法 | 描述 |

| --- | --- | --- |

| boolean | add(E e) | 将指定的元素添加到此列表的尾部。 |

| void | add(int index, E element) | 将指定的元素插入此列表中的指定位置。 |

| boolean | addAll(Collection<? extends E> c) | 按照指定 collection 的迭代器所返回的元素顺序,将该 collection 中的所有元素添加到此列表的尾部。 |

| boolean | addAll(int index, Collection<? extends E> c) | 从指定的位置开始,将指定 collection 中的所有元素插入到此列表中。 |

| void | clear() | 移除此列表中的所有元素。 |

| Object | clone() | 返回此 ArrayList 实例的浅表副本。 |

| boolean | contains(Object o) | 如果此列表中包含指定的元素,则返回 true。 |

| void | ensureCapacity(int minCapacity) | 如有必要,增加此 ArrayList 实例的容量,以确保它至少能够容纳最小容量参数所指定的元素数。 |

| E | get(int index) | 返回此列表中指定位置上的元素。 |

| int | indexOf(Object o) | 返回此列表中首次出现的指定元素的索引,或如果此列表不包含元素,则返回 -1。 |

| boolean | isEmpty() | 如果此列表中没有元素,则返回 true |

| int | lastIndexOf(Object o) | 返回此列表中最后一次出现的指定元素的索引,或如果此列表不包含索引,则返回 -1。 |

| E | remove(int index) | 移除此列表中指定位置上的元素。 |

| boolean | remove(Object o) | 移除此列表中首次出现的指定元素(如果存在) |

| protected void | removeRange(int fromIndex, int toIndex) | 移除列表中索引在 fromIndex(包括)和 toIndex(不包括)之间的所有元素。 |

| E | set(int index, E element) | 用指定的元素替代此列表中指定位置上的元素。 |

| int | size() | 返回此列表中的元素数。 |

| Object\[\] | toArray() | 按适当顺序(从第一个到最后一个元素)返回包含此列表中所有元素的数组。 |

| T\[\] | toArray(T\[\] a) | 按适当顺序(从第一个到最后一个元素)返回包含此列表中所有元素的数组;返回数组的运行时类型是指定数组的运行时类型。 |

| void | trimToSize() | 将此 ArrayList 实例的容量调整为列表的当前大小。 |



[]( )2 ArrayList常用操作

=========================================================================



[]( )2.1 ArrayList遍历

-------------------------------------------------------------------------



ArrayList支持三种遍历方式:迭代器遍历、随机访问遍历、增强for遍历



public static void main(String[] args) {

List<Integer> list = Arrays.asList(1, 7, 5, 3, 8, 2);

// 迭代器遍历

Iterator<Integer> it = list.iterator();

while (it.hasNext()) {

	int value = (int) it.next();

	System.out.println(value + " ");

}



// 随机访问遍历

for (int i = 0; i < list.size(); i++) {

	int value = list.get(i);

	System.out.println(value + " ");

}



// 增强for遍历

for (int value : list) {

	System.out.print(value + " ");

}

}




[]( )2.2 ArrayList排序

-------------------------------------------------------------------------



ArrayList集合排序依赖于Collections.sort(),其默认是按升序排序的,如果想要降序排列,需重写Collections.sort()方法。



public static void main(String[] args) {

List<Integer> list = Arrays.asList(1, 7, 5, 3, 8, 2);



// 按照字典顺序排序

Collections.sort(list);

System.out.println("默认排序:" + list);



// 自定义排序

Collections.sort(list, new Comparator<Integer>() {

	@Override

	public int compare(Integer o1, Integer o2) {

		int i = o1.compareTo(o2);

		// int、double型,可以直接用o1 > o2做if的判断条件,String类型只能用compareTo方法

		if (i > 0) 

			return -1;

		return 1;

	}

});

System.out.println("自定义排序:" + list);

}




运行结果:



默认排序:[1, 2, 3, 5, 7, 8]

自定义排序:[8, 7, 5, 3, 2, 1]




[]( )2.3 ArrayList删除元素

---------------------------------------------------------------------------



现在有 \[a,a,b,c,e,a,d\] 这么一个ArrayList集合,删除该集合中的所有的"a"。也许有人觉得很简单,并给出下面代码:



public static void main(String[] args) {

List<String> list = new ArrayList<>();

list.add("a");

list.add("a");

list.add("d");

list.add("c");

list.add("a");

list.add("e");

list.add("m");



// 错误的删除方法:

for (int i = 0; i < list.size(); i++) {

	String value = list.get(i);

	if (value.equals("a"))

		list.remove(i);

}

System.out.println(list);

}




运行结果:



[a, d, c, e, m]




可以看到,当有连续两个以上a元素时,最终会保留一个。原因是,删除元素后,ArrayList集合的索引重新排列,删除元素后面的元素索引全部向前移动一位,本例中,删除第一个a后,第二个a的索引就由1变成了0,而for循环已经运行过0了,导致第二个a未被删除。  

**正确的做法是倒序遍历删除:**



for (int i = list.size()-1; i >= 0; i–) {

String value = list.get(i);

if (value.equals("a"))

	list.remove(i);

}




[]( )3 ArrayList部分方法源码(基于JDK1.8)

=====================================================================================



[]( )3.1 get(int index)

----------------------------------------------------------------------------



// 先检查index范围是否正确,正确的话从数组里取出元素

public E get(int index) {

rangeCheck(index);

return elementData(index);

}

E elementData(int index) {

return (E) elementData[index];

}

private void rangeCheck(int index) {

// 如果index 大于 存储的个数,则抛出异常

if (index >= size)

// outOfBoundsMsg里面就是简单的字符串拼接。

throw new IndexOutOfBoundsException(outOfBoundsMsg(index));

}




[]( )3.2 add(E e)

----------------------------------------------------------------------



public boolean add(E e) {

// 对于刚初始化的数组,要初始化它的大小

// 判断数组大小是否足够,如果不够大,扩容

// 对于扩容要判断是否到达数组的最大数量

ensureCapacityInternal(size + 1);

//赋值,然后指针走到下一个空位

elementData[size++] = e;

return true;

}

private void ensureCapacityInternal(int minCapacity) {

// 上述情况一:初始化数组的大小

if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {

	// 取minCapacity和DEFAULT_CAPACITY中较大的那个

	minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);

}

// 检查有没有扩容的必要

ensureExplicitCapacity(minCapacity);

}

private void ensureExplicitCapacity(int minCapacity) {

// 修改次数的计数器(在AbstractList中定义的)

modCount++;

// 如果需要的空间大小 > 当前数组的长度,则进行扩容

if (minCapacity - elementData.length > 0)

	grow(minCapacity);

}

private void grow(int minCapacity) {

// 记录旧的length

int oldCapacity = elementData.length;

// 扩容1.5倍, 位运算符效率更高

int newCapacity = oldCapacity + (oldCapacity >> 1);

// 判断有没有溢出

if (newCapacity - minCapacity < 0)

	newCapacity = minCapacity;

// 判断有没有超过最大的数组大小

if (newCapacity - MAX_ARRAY_SIZE > 0)

	//计算最大的容量

	newCapacity = hugeCapacity(minCapacity);

// 旧数组拷贝到新的大小数组

elementData = Arrays.copyOf(elementData, newCapacity);

}

// 最大的容量

private static int hugeCapacity(int minCapacity) {

// 大小溢出

if (minCapacity < 0)

	throw new OutOfMemoryError();

// 需要的最小容量 > 数组最大的长度,则取Integer的最大值,否则取数组最大长度

return (minCapacity > MAX_ARRAY_SIZE) ?

	Integer.MAX_VALUE :

MAX_ARRAY_SIZE;

}




[]( )3.3 remove(Object o)

------------------------------------------------------------------------------



public boolean remove(Object o) {

// 判断o为null,loop遍历找到为null的元素

if (o == null) {

	for (int index = 0; index < size; index++)

  		if (elementData[index] == null) {

    	fastRemove(index);

    	return true;

  	}

最后

针对最近很多人都在面试,我这边也整理了相当多的面试专题资料,也有其他大厂的面经。希望可以帮助到大家。

下面的面试题答案都整理成文档笔记。也还整理了一些面试资料&最新2021收集的一些大厂的面试真题(都整理成文档,小部分截图)

在这里插入图片描述

最新整理电子书

在这里插入图片描述

public boolean remove(Object o) {

// 判断o为null,loop遍历找到为null的元素

if (o == null) {

	for (int index = 0; index < size; index++)

  		if (elementData[index] == null) {

    	fastRemove(index);

    	return true;

  	}

最后

针对最近很多人都在面试,我这边也整理了相当多的面试专题资料,也有其他大厂的面经。希望可以帮助到大家。

下面的面试题答案都整理成文档笔记。也还整理了一些面试资料&最新2021收集的一些大厂的面试真题(都整理成文档,小部分截图)

[外链图片转存中…(img-R2TujmZu-1714512056697)]

最新整理电子书

[外链图片转存中…(img-TW3yCrQJ-1714512056698)]

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值