深入理解List的toArray(T[] a)方法在二维数组复制里的写法

我们都很清楚list带有两个重载的toArray()方法:

  1. toArray()
  2. toArray(T[] a)

第一个我就不多解释了,返回的是一个Object数组,实际上用的很少,这篇文章主要想写的是在刷leetcode的题目406. 根据身高重建队列的过程中遇到的List的toArray(T[] a)方法在二维数组复制里的写法。话不多说,先上源码:

/**
 * Returns an array containing all of the elements in this list in proper
 * sequence (from first to last element); the runtime type of the returned
 * array is that of the specified array.  If the list fits in the
 * specified array, it is returned therein.  Otherwise, a new array is
 * allocated with the runtime type of the specified array and the size of
 * this list.
 *
 * <p>If the list fits in the specified array with room to spare
 * (i.e., the array has more elements than the list), the element in
 * the array immediately following the end of the collection is set to
 * <tt>null</tt>.  (This is useful in determining the length of the
 * list <i>only</i> if the caller knows that the list does not contain
 * any null elements.)
 *
 * @param a the array into which the elements of the list are to
 *          be stored, if it is big enough; otherwise, a new array of the
 *          same runtime type is allocated for this purpose.
 * @return an array containing the elements of the list
 * @throws ArrayStoreException if the runtime type of the specified array
 *         is not a supertype of the runtime type of every element in
 *         this list
 * @throws NullPointerException if the specified array is null
 */
@SuppressWarnings("unchecked")
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);
    if (a.length > size)
        a[size] = null;
    return a;
}
  1. 判断数组a的长度和size的大小,这里size是list用来存储元素的数组元素个数,这个变量已经在类里定义好,如果a数组的长度小于size,调用工具类Arrays.copyOf()方法按照size的大小拷贝数组,elementData就是list用来存储元素的数组,泛型由a.getClass()得到并且传入。

  2. 如果数组a的长度length不小于list元素个数,即a.length>=size
    将会调用System.arraycopy(elementData, 0, a, 0, size)将ArrayList里的元素数组elementData中的size个元素拷贝到a数组中。

  3. 判断a.length >size,如果大于的话,会在a[size]位置设置一个null,置空是为了判断数组结束的位置。


好了,源码就这么多,回归正题,在leetcode二维数组的题目里,一般我们会这么放置元素ArrayList<int[]> list = new ArrayList<>();,程序结束以后,一般说来会要返回一个int[][]的二维数组,这个时候就要使用到toArray(T[] a)方法,这个时候你会说了,这多简单,这么写:

list.toArray(new int[list.size()][2]);

这里的2是题目设定的2维点坐标。好吧,这样当然是对的,但是我多次运行后,时间和内存效率大概是这样:
在这里插入图片描述
其实也可以这么写:

list.toArray(new int[0][]);

在这里插入图片描述
解释一下为什么能这样写:

  1. 二维数组的第2个维度为什么可以不填?因为源码里给出了,我们只需要a.getClass()得到泛型,也就是得到int[],并不需要这个数组的长度
  2. 二维数组的第1个维度为什么可以填0?上面源码分析的第1点已经提到了,传入数组的长度小于list的元素个数size时,是默认使用size作为数组复制的长度

总结

list.toArray(new int[0][])这种写法确实有性能上的提升,多次运行的时间基本是在9-10秒内,内存占用也在43-44浮动,问了一下大佬,大佬说老手子们在开发中惯用的也是这种写法,所以大家不妨学习一下

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
要将list实体转换为二维数组,可以使用以下方法: 1. 首先,创建一个二维数组,其大小为list的大小和实体对象的属性数量。例如,如果list有n个实体对象,每个实体对象有m个属性,则创建一个大小为n×m的二维数组。 2. 然后,使用循环遍历list中的每个实体对象。对于每个实体对象,再次使用循环遍历其属性,并将属性的值存储在二维数组的相应位置上。 3. 最后,返回转换后的二维数组。 以下是一个示例代码,演示了如何将list实体转换为二维数组: ```java public static <T> Object\[\]\[\] toArray(List<T> list, String\[\] variable) { Object\[\]\[\] obj = new Object\[list.size()\]\[variable.length\]; for (int i = 0; i < list.size(); i++) { final T t = list.get(i); for (int j = 0; j < variable.length; j++) { obj\[i\]\[j\] = getVariableValue(t, variable\[j\]); } } return obj; } private static <T> Object getVariableValue(T t, String variable) { // 根据实际情况获取实体对象的属性值 // 这假设实体对象的属性都是公共的,可以直接通过反射获取属性值 try { Field field = t.getClass().getDeclaredField(variable); field.setAccessible(true); return field.get(t); } catch (NoSuchFieldException | IllegalAccessException e) { e.printStackTrace(); } return null; } ``` 这个方法可以将list中的实体对象转换为一个二维数组,其中每一行代表一个实体对象,每一列代表实体对象的一个属性值。你可以根据实际情况修改代码中的getVariableValue方法,以适应你的实体对象的属性获取方式。 #### 引用[.reference_title] - *1* *2* [把List转换成二维数组](https://blog.csdn.net/iteye_6967/article/details/81928592)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [list对象转二维数组](https://blog.csdn.net/jiahao791869610/article/details/98642486)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值