集合与数组互转需用toArray()和Arrays.asList(),前者推荐new T[0]避免类型错误,后者返回固定大小列表且与原数组联动,修改会相互影响,需新建集合以获得可变实例。

在Java中,集合(
Collection
Array
要实现Java中集合与数组的互转,我们主要依赖
Collection
toArray()
Arrays
asList()
1. 集合转数组 (Collection to Array)
当我们需要将一个集合中的元素转换成数组时,
Collection
toArray()
立即学习“Java免费学习笔记(深入)”;
Object[] toArray()
Object
ClassCastException
List<String> stringList = new ArrayList<>(Arrays.asList("Apple", "Banana", "Cherry"));
Object[] objectArray = stringList.toArray();
// 此时 objectArray 是 Object[] 类型,如果直接访问特定方法会报错或需要强转
// String first = (String) objectArray[0]; // 需要强制转换
System.out.println("Object数组: " + Arrays.toString(objectArray));T[] toArray(T[] a)
List<String> stringList = new ArrayList<>(Arrays.asList("Apple", "Banana", "Cherry"));
// 推荐做法:传入一个类型匹配的空数组,让toArray方法自动创建合适大小的数组
String[] stringArray = stringList.toArray(new String[0]);
System.out.println("String数组: " + Arrays.toString(stringArray));
// 另一种做法:预先分配大小,如果集合元素少于数组大小,多余位置会填充null
String[] preAllocatedArray = new String[5];
String[] result = stringList.toArray(preAllocatedArray);
System.out.println("预分配数组填充结果: " + Arrays.toString(result));
System.out.println("是否是同一个数组实例? " + (preAllocatedArray == result)); // true,因为预分配数组足够大
// 如果预分配数组不够大,toArray会创建一个新的
String[] smallArray = new String[1];
String[] newArray = stringList.toArray(smallArray);
System.out.println("小数组填充结果: " + Arrays.toString(newArray));
System.out.println("是否是同一个数组实例? " + (smallArray == newArray)); // false,因为创建了新数组2. 数组转集合 (Array to Collection)
将数组转换成集合,我们主要使用
Arrays.asList()
Arrays.asList(T... a)
List
List
ArrayList
Arrays
List
List
set()
add()
remove()
UnsupportedOperationException
String[] fruitsArray = {"Grape", "Kiwi", "Mango"};
List<String> fixedSizeList = Arrays.asList(fruitsArray);
System.out.println("固定大小列表: " + fixedSizeList);
// 修改列表会影响原始数组
fixedSizeList.set(0, "Pineapple");
System.out.println("修改后列表: " + fixedSizeList);
System.out.println("原始数组被修改: " + Arrays.toString(fruitsArray));
// 尝试添加或删除会抛出异常
try {
fixedSizeList.add("Orange");
} catch (UnsupportedOperationException e) {
System.out.println("尝试添加元素失败: " + e.getMessage());
}
// 如果你需要一个可变大小的List,通常会这样做:
List<String> mutableList = new ArrayList<>(Arrays.asList(fruitsArray));
mutableList.add("Orange");
System.out.println("可变列表: " + mutableList);这其实是一个关于“适配”的问题。Java生态系统庞大,历史悠久,很多早期的API或者为了追求极致性能的底层实现,往往会直接操作数组。比如,
String
split()
String[]
Collection
在我看来,这种来回转换,主要是因为:
ArrayList
Set
Map
new T[0]
ClassCastException
所以,与其说我们“总是在来回转换”,不如说我们是在根据不同的需求和上下文,选择最合适的数据结构,并在需要时进行无缝切换。这是一种平衡,也是一种妥协。
toArray()
toArray()
主要陷阱:
toArray()
Object[]
collection.toArray()
SpecificType[]
List<Integer> numbers = Arrays.asList(1, 2, 3); // 编译通过,但运行时会抛 ClassCastException // Integer[] intArray = (Integer[]) numbers.toArray(); // 错误!
这是因为
numbers.toArray()
Object[]
Integer[]
Integer
Object
Integer[]
Object[]
传入参数数组的尺寸影响行为: 当使用
collection.toArray(T[] a)
a
List<String> names = Arrays.asList("Alice", "Bob");
String[] smallArr = new String[1];
String[] resultArr = names.toArray(smallArr);
// 此时 resultArr 是一个新的数组,smallArr 并没有被填充
System.out.println("smallArr: " + Arrays.toString(smallArr)); // [null]
System.out.println("resultArr: " + Arrays.toString(resultArr)); // [Alice, Bob]
System.out.println("smallArr == resultArr: " + (smallArr == resultArr)); // false最佳实践:
使用 collection.toArray(new T[0])
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
String[] nameArray = names.toArray(new String[0]);
System.out.println("最佳实践: " + Arrays.toString(nameArray));这里的
new String[0]
toArray
使用 collection.toArray(new T[collection.size()])
new T[0]
toArray
List<Integer> scores = Arrays.asList(90, 85, 92);
Integer[] scoreArray = scores.toArray(new Integer[scores.size()]);
System.out.println("预分配大小: " + Arrays.toString(scoreArray));然而,对于绝大多数应用来说,
new T[0]
new T[0]
Arrays.asList()
Arrays.asList()
List
ArrayList
LinkedList
需要特别注意的地方:
固定大小: 这是最重要的限制。由
Arrays.asList()
List
add()
remove()
clear()
UnsupportedOperationException
String[] colors = {"Red", "Green", "Blue"};
List<String> colorList = Arrays.asList(colors);
try {
colorList.add("Yellow"); // 抛出 UnsupportedOperationException
} catch (UnsupportedOperationException e) {
System.out.println("无法添加元素: " + e.getMessage());
}
try {
colorList.remove(0); // 抛出 UnsupportedOperationException
} catch (UnsupportedOperationException e) {
System.out.println("无法删除元素: " + e.getMessage());
}这个坑我刚学Java的时候就踩过,当时觉得很奇怪,一个List怎么就不能加减元素了?后来才明白它背后的设计意图。
与原始数组的联动:
Arrays.asList()
List
List
set()
String[] fruits = {"Apple", "Banana"};
List<String> fruitList = Arrays.asList(fruits);
System.out.println("原始数组: " + Arrays.toString(fruits)); // [Apple, Banana]
System.out.println("转换列表: " + fruitList); // [Apple, Banana]
fruitList.set(0, "Orange"); // 修改列表
System.out.println("修改列表后,原始数组: " + Arrays.toString(fruits)); // [Orange, Banana]
fruits[1] = "Grape"; // 修改数组
System.out.println("修改数组后,转换列表: " + fruitList); // [Orange, Grape]这种联动性既是它的特性,也可能是潜在的陷阱,如果开发者不清楚这一点,可能会导致意料之外的数据变化。
如何获得一个可变的集合?
如果你需要一个可以自由添加、删除元素,并且与原始数组解耦的
List
Arrays.asList()
String[] animals = {"Cat", "Dog"};
List<String> mutableAnimalList = new ArrayList<>(Arrays.asList(animals));
mutableAnimalList.add("Elephant"); // 现在可以自由添加了
System.out.println("可变集合: " + mutableAnimalList); // [Cat, Dog, Elephant]
System.out.println("原始数组未受影响: " + Arrays.toString(animals)); // [Cat, Dog]这种方式是更常见的需求,它确保了你得到一个完全独立的、可操作的集合实例。
以上就是Java中集合与数组互转技巧的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号