上一篇地址:赶紧收藏!2024 年最常见 100道 Java 基础面试题(十三)-CSDN博客
二十七、ArrayList
和Vector
的区别是什么?
ArrayList
和Vector
都是Java中基于动态数组实现的List
接口的实现类,它们都允许存储一组元素,并提供对这些元素的动态访问。尽管它们在功能上相似,但存在一些关键的区别:
-
同步性:
Vector
是同步的,即它是线程安全的。这意味着Vector
的所有方法都是同步的,可以在多线程环境中安全使用。ArrayList
在Java 7及以前的版本中不是线程安全的。从Java 8开始,虽然ArrayList
本身不是线程安全的,但是引入了新的并发集合类,如CopyOnWriteArrayList
,用于在某些并发场景中提供线程安全的替代。
-
性能:
- 由于
Vector
是同步的,它在单线程环境中的性能通常不如ArrayList
,因为ArrayList
不需要承担同步的开销。 - 在多线程环境中,如果需要线程安全的
List
,可以使用Vector
,但考虑到性能,更推荐使用Collections.synchronizedList()
包装的ArrayList
,或者使用专门的并发集合类。
- 由于
-
遗留代码:
Vector
是一个较老的类,它源自早期的Java版本,那时对性能的关注不如现在,线程安全是更重要的考虑。ArrayList
是Java集合框架中较新、更常用的类,它提供了更好的性能。
-
方法:
Vector
提供了一些额外的方法,如addElement()
和removeElement()
,这些方法是用于向后兼容的,而在ArrayList
中,这些操作通过add()
和remove()
方法实现。
-
容量增加策略:
Vector
在需要增加容量时,通常会增加其当前容量的两倍,而ArrayList
默认增加50%的容量。
-
使用场景:
- 在单线程环境中,如果不需要线程安全,应优先使用
ArrayList
。 - 在多线程环境中,如果需要线程安全的集合,可以考虑使用
Vector
,但更推荐使用CopyOnWriteArrayList
或通过Collections.synchronizedList()
包装的ArrayList
。
- 在单线程环境中,如果不需要线程安全,应优先使用
示例代码:
import java.util.ArrayList;
import java.util.Vector;
public class ArrayListVsVector {
public static void main(String[] args) {
// ArrayList示例
ArrayList<String> arrayList = new ArrayList<>();
arrayList.add("Java");
arrayList.add(0, "Python"); // 在索引0的位置插入"Python"
// Vector示例
Vector<String> vector = new Vector<>();
vector.add("Java");
vector.insertElementAt("Python", 0); // 在索引0的位置插入"Python"
}
}
总结:
ArrayList
和Vector
都实现了List
接口,提供动态数组的功能。ArrayList
在单线程环境中性能更好,而Vector
提供了线程安全的操作方法。- 在多线程环境中,应谨慎选择
Vector
,并考虑使用其他线程安全的集合类。
二十八、Array
和ArrayList
有何区别?
Array
和ArrayList
是Java中存储一系列元素的两种不同的方式,它们在多个方面有所区别:
-
类型限制:
Array
是固定大小的,它的类型在声明时就确定了,并且这个类型是强类型的。例如,如果你声明了一个int[]
类型的数组,那么它只能存储int
类型的数据。ArrayList
是可变的,它可以在运行时调整大小,并且它是一个泛型类,可以存储任何类型的Object
。
-
性能:
Array
提供更快的访问时间,因为它是一个连续的内存空间,CPU缓存机制可以优化访问速度。ArrayList
的访问速度通常比Array
慢,因为它是基于Object
数组实现的,并且可能涉及额外的内存分配和数组复制操作。
-
内存使用:
Array
通常使用更少的内存,因为它只存储元素本身。ArrayList
使用更多的内存,因为它需要存储额外的信息,如大小、空余空间等。
-
操作:
Array
一旦创建,其大小就不能改变。如果需要更大的数组,必须创建一个新的数组并复制数据。ArrayList
可以动态地添加和移除元素,不需要手动管理内存。
-
多维支持:
- Java支持多维数组,例如
int[][]
,这使得处理多维数据结构变得简单。 ArrayList
本身不支持多维,但可以通过ArrayList< ArrayList< Type >>
的方式来模拟多维列表。
- Java支持多维数组,例如
-
线程安全性:
Array
是基本数据类型,没有线程安全的保证,但也没有额外的同步开销。ArrayList
不是线程安全的。如果需要线程安全的集合,可以使用Vector
或Collections.synchronizedList(new ArrayList<>())
。
-
Null值:
Array
中的元素可以是该类型的默认值(例如,int
类型的默认值是0
)。ArrayList
可以包含null
值,它更加灵活。
-
增强的for循环(foreach):
- 从Java 5开始,可以使用增强的for循环来遍历
ArrayList
,这使得代码更加简洁。 - 虽然也可以使用增强的for循环遍历
Array
,但语法上不如遍历ArrayList
直观。
- 从Java 5开始,可以使用增强的for循环来遍历
示例代码:
// Array示例
int[] intArray = new int[5];
intArray[0] = 1;
intArray[1] = 2;
// ArrayList示例
List<Integer> intList = new ArrayList<>();
intList.add(1);
intList.add(0, 0); // 在索引0的位置插入元素0
总结:
Array
是固定大小的,适合在编译时就确定了大小且不需要改变的场景。ArrayList
是可变的,适合在运行时需要动态改变集合大小时使用。- 选择使用
Array
还是ArrayList
应基于程序的具体需求和性能考虑。