在 Java 中,可以通过以下方式实现集合、数组和字符串之间的相互转换。
一、集合和数组的相互转化
①、将集合转为数组:(toArray 方法)
List<String> list = new ArrayList<>();
list.add("apple");
list.add("banana");
list.add("orange");
// 传入数组类型
String[] arr = list.toArray(new String[0]);
// [apple, banana, orange]
System.out.println(Arrays.toString(arr));
②、将数组转为集合:(asList 方法)
String[] arr = {"apple", "banana", "orange"};
List<String> list = Arrays.asList(arr);
System.out.println(list); // [apple, banana, orange]
注意:将数组转为集合时,使用的是 Arrays.asList()
方法。将数组转换为集合后,得到的集合不支持增加或删除元素(因为底层存储的仍然是数组),只能修改元素。如果需要增加或删除元素,需要将其转换为可变的 List:
将 Arrays.asList()
方法返回的 List 转换为可变的 List,可以使用如下两种方式:
- 构造一个新的 ArrayList 对象,并将
Arrays.asList()
返回的 List 作为构造方法的参数传入:String[] arr = {"apple", "banana", "orange"}; // 将 Arrays.asList() 返回的 List 作为构造方法的参数传入 List<String> list = new ArrayList<>(Arrays.asList(arr)); list.add("peach"); System.out.println(list); // [apple, banana, orange, peach]
- 使用
Collections.addAll()
方法将Arrays.asList()
返回的 List 添加到一个新的 ArrayList 对象中:String[] arr = {"apple", "banana", "orange"}; List<String> list = new ArrayList<>(); // 将 Arrays.asList() 返回的 List 添加到一个新的 ArrayList 对象中 Collections.addAll(list, arr); list.add("peach"); System.out.println(list); // [apple, banana, orange, peach]
需要注意的是,这两种方式都会创建一个新的可变的 List 对象。如果只是需要在原有的 List 中增加或删除元素,可以使用 list.add()
或 list.remove()
等方法。
关于这一点详细的说明可以参考:(Java 核心术 卷 I——集合)
二、集合和字符串的相互转化
① 、将集合转为字符串:
List<String> list = new ArrayList<>();
list.add("apple");
list.add("banana");
list.add("orange");
String str = String.join(",", list);
System.out.println(str); // apple,banana,orange
②、将字符串转为集合:
String str = "apple,banana,orange";
List<String> list = Arrays.asList(str.split(","));
System.out.println(list); // [apple, banana, orange]
注意:使用 String.join()
方法可以将集合中的元素连接成字符串,其中参数为连接符,连接符会插入每个元素之间。使用 split()
方法可以将字符串按照指定的分隔符分割为数组,再使用 Arrays.asList()
方法将其转换为 List。需要注意的是,Arrays.asList()
方法返回的 List 是不可变的固定大小的 List,无法增加或删除元素,如果需要增加或删除元素,需要将其转换为可变的 List。
与数组转集合的方法类似,字符串转集合转换为可变的List也有两种方法:
- 构造一个新的 ArrayList 对象,并将
Arrays.asList()
返回的 List 作为构造方法参数传入:String str = "apple,banana,orange"; String[] arr = str.split(","); List<String> list = new ArrayList<>(Arrays.asList(arr)); list.add("peach"); System.out.println(list); // [apple, banana, orange, peach]
- 使用
Collections.addAll()
方法将Arrays.asList()
返回的 List 添加到一个新的 ArrayList 对象中:String str = "apple,banana,orange"; String[] arr = str.split(","); List<String> list = Arrays.asList(arr); List<String> newList = new ArrayList<>(list); newList.add("peach"); System.out.println(newList); // [apple, banana, orange, peach]
三、数组和字符串的相互转化
①、将数组转为字符串:
String[] arr = {"apple", "banana", "orange"};
String str = String.join(",", arr);
System.out.println(str); // apple,banana,orange
②、将字符串转为数组:
String str = "apple,banana,orange";
String[] arr = str.split(",");
System.out.println(Arrays.toString(arr)); // [apple, banana, orange]
以上就是 Java 中集合、数组和字符串之间的相互转换的示例。
四、关于String[] arr = list.toArray(new String[0]);源码分析
当然抛开前面的集合转为数组的方法,list.toArray(new String[0]) 中 new String[0]什么意思,为什么要写new String[0] 不写0可以写别的吗?
经过查阅资料发现:在将List转换为数组时,传入new String[0]参数是为了告诉JVM这个toArray的返回结果是一个String数组。这种方式更加高效,因为如果传入的数组长度不够,数组会被重新生成,而使用0长度的数组,则可以避免这种情况,同时也不会浪费内存空间。
但具体什么情况,还是下个断点,debug模式下看一下源码是怎么写的吧。
这段源码是Java集合框架中List接口的实现,作用是将List中的所有元素按照顺序存储到指定的数组中,并返回这个数组。下面逐行解释这段代码的作用:
@SuppressWarnings("unchecked")
public <T> T[] toArray(T[] a) {
该方法是toArray方法的具体实现,其中使用了泛型T来表示要存储元素的数组类型。由于返回的数组类型与传入的参数数组类型相同,因此需要使用SuppressWarnings注解来避免编译器警告。
if (a.length < size)
// Make a new array of a's runtime type, but my contents:
return (T[]) Arrays.copyOf(elementData, size, a.getClass());
如果传入的数组长度小于List中元素的个数,就创建一个元素类型为a的运行时类型的新数组,将List中的元素复制到这个新数组中。
System.arraycopy(elementData, 0, a, 0, size);
如果传入的数组足够大,就直接将List中的元素复制到传入的数组a中。
if (a.length > size)
a[size] = null;
如果传入的数组长度比List中的元素个数大,就在传入的数组的最后一个元素位置上设置null值,用来标记数组的有效长度。
return a;
最后返回传入的数组a。