Java List toArray(T[] a) 实现
我只是查看 List 接口中定义的方法:
返回一个数组,其中包含按正确顺序排列的列表中的所有元素;返回数组的运行时类型是指定数组的运行时类型。如果该列表适合指定的数组,则将其返回其中。否则,将使用指定数组的运行时类型和该列表的大小分配一个新数组。 如果列表适合指定的数组,并且有空闲空间(即数组的元素多于列表),则数组中紧跟集合末尾的元素将设置为 null。仅当调用者知道列表不包含任何空元素时,这才有助于确定列表的长度。
<前><代码>; T[] toArray(T[] a);
我只是想知道为什么它是这样实现的,基本上如果你向它传递一个长度 < 的数组。对于list.size(),它只会创建一个新的并返回它。因此在方法参数中创建新的数组对象是没有用的。
此外,如果您使用列表的大小向它传递一个足够长的数组,如果返回与对象相同的对象 - 实际上没有必要返回它,因为它是相同的对象,但为了清楚起见还是可以的。
问题是我认为这会导致代码效率稍低,在我看来 toArray 应该简单地接收类并返回带有内容的新数组。
有什么原因不这样编码吗?
I was just looking at the method defined in the List interface:
Returns an array containing all of the elements in this list in the correct order; 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.
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 null. This is useful in determining the length of the list only if the caller knows that the list does not contain any null elements.<T> T[] toArray(T[] a);
And I was just wondering why is it implemented this way, basically if you pass it an array with a length < to the list.size(), it will simply create a new one and return it. Therefore the creation of the new Array Object in the method parameter is useless.
Additionally if you pass it an array long enough using the size of the list if returns that same object with the objects - really no point in returning it since it is the same object but ok for clarity.
The problem is that I think this promotes slightly inefficient code, in my opinion toArray should simply receive the class and just return the new array with the contents.
Is there any reason why it is not coded that way?.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
也许它有一个运行时类型?
来自维基:
Maybe so it has a runtime type?
From wiki:
正如其他人提到的,有几个不同的原因:
As mentioned by others, there are a couple different reasons:
这很可能是为了允许您重用数组,因此您基本上可以避免某些用例的(相对昂贵的)数组分配。另一个较小的好处是调用者可以更有效地实例化数组,因为 toArray() 必须使用“java.lang.reflect.Array.newInstance”方法。
Most likely this is to allow you to reuse arrays, so you basically avoid (relatively costly) array allocation for some use cases. Another much smaller benefit is that caller can instantiate array slightly more efficiently, since toArray() must use 'java.lang.reflect.Array.newInstance' method.
此方法是 1.5 之前的 Java 的延续。这是 javadoc
当时,这是将列表转换为可具体化数组的唯一方法。
这是一个模糊的事实,但是尽管您可以在 Object[] 数组中存储任何内容,但您不能将此数组转换为更具体的类型,例如
看似更高效的
List.toArray()
就是这样做的,它创建一个通用的Object
数组。在 Java 泛型出现之前,进行类型安全传输的唯一方法就是采用这种方法:
值得庆幸的是,泛型使这些阴谋变得过时。保留此方法是为了提供与 1.5 之前的代码的向后兼容性。
This method is a holdover from pre-1.5 Java. Here is the link to javadoc
Back then it was the only way to convert a list to a reifiable array.
It is an obscure fact, but although you can store anything in the Object[] array, you cannot cast this array to more specific type, e.g.
Seemingly more efficient
List.toArray()
does just that, it creates a genericObject
array.Before Java generics, the only way to do a type-safe transfer was to have this cludge:
Thankfully generics made these kind of machinations obsolete. This method was left there to provide backward compatibility with pre 1.5 code.
我的猜测是,如果您在调用
toArray(T[])
时已经知道T
的具体类型,那么仅声明一个数组会更具性能不管它是什么,都比让List
实现为您调用Arrays.newInstance()
更好——而且在许多情况下您可以重复使用该数组。但如果它让你烦恼,那么编写一个实用方法就很容易了:(
请注意,无法编写
E[] ToArray(Collectionc)
,因为没有办法在运行时创建一个没有Class
对象的E
数组,并且无法获取E
的Class
对象> 在运行时,因为泛型已被删除。)My guess is that if you already know the concrete type of
T
at the point you're callingtoArray(T[])
, it's more performant to just declare an array of whatever it is than make theList
implementation callArrays.newInstance()
for you -- plus in many cases you can re-use the array.But if it annoys you, it's easy enough to write a utility method:
(Note that there's no way to write
<E> E[] ToArray(Collection<E> c)
, because there's no way to create an array ofE
at runtime without aClass
object, and no way to get aClass
object forE
at runtime, because the generics have been erased.)