List转数组:Call to 'toArray()' with pre-sized array argument 'new String[list.size()]'
代码示例:
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("java");
list.add("flink");
list.add("spring");
//第一种写法:该写法不规范
String[] array1 = list.toArray(new String[list.size()]);
//第二种写法:推荐写法
//(可读性强,空数组为静态,无需创建数组;不过底层代码还是要创建数组的,但是jvm已做优化,可以忽略)
String[] array2 = list.toArray(new String[0]);
//第三种写法
String[] array3 = list.stream().toArray(String[]::new);
}
String[] array = list.toArray(new String[list.size()])
提示如下:
Call to 'toArray()' with pre-sized array argument 'new String[list.size()]' less...
Inspection info: There are two styles to convert a collection to an array: either using a pre-sized array (like c.toArray(new String[c.size()])) or using an empty array (like c.toArray(new String[0]).
In older Java versions using pre-sized array was recommended, as the reflection call which is necessary to create an array of proper size was quite slow. However since late updates of OpenJDK 6 this call was intrinsified, making the performance of the empty array version the same and sometimes even better, compared to the pre-sized version. Also passing pre-sized array is dangerous for a concurrent or synchronized collection as a data race is possible between the size and toArray call which may result in extra nulls at the end of the array, if the collection was concurrently shrunk during the operation.
This inspection allows to follow the uniform style: either using an empty array (which is recommended in modern Java) or using a pre-sized array (which might be faster in older Java versions or non-HotSpot based JVMs).
大致意思如下:
有两种样式可将集合转换为数组:
- 使用预先调整大小的数组:
c.toArray(new String[c.size()])
--不推荐 - 使用空数组:
c.toArray(new String[0])
--推荐
在旧的Java版本中,建议使用预先调整大小的数组,因为创建适当大小的数组所需的反射调用非常慢。但是,由于OpenJDK 6的最新更新,这个调用是内在的,使得空数组版本的性能与预先设置的版本相同,有时甚至更好。同时,传递预大小的数组对于并发或同步的集合是危险的,因为如果集合在操作期间同时收缩,那么在size()
和toArray()
调用之间可能会发生数据竞争,这可能会导致数组末尾出现额外的空值。
这种检查允许遵循统一的风格:要么使用空数组(在现代Java中是推荐的),要么使用预先设置大小的数组(在较旧的Java版本或非基于热点的jvm中可能更快
源码
看下ArrayList的toArray源码
//存放数据的真实数组;ArrayList 底层时数据实现
T[] elementData;
//ArrayList 真实大小
private int size;
//转换数组操作
public <T> T[] toArray(T[] a) {
if (a.length < size)
// Make a new array of a's runtime type, but my contents:
return (T[]) Arrays.copyOf(elementData, size, a.getClass());
System.arraycopy(elementData, 0, a, 0, size); //1
if (a.length > size)
a[size] = null;
return a;
}
参考:
https://stackoverflow.com/questions/174093/toarraynew-myclass0-or-toarraynew-myclassmylist-size
指正交流微信: snail_java