当前位置: 首页 > 面试题库 >

为什么Java ArrayList使用逐元素转换而不是逐数组转换?

颛孙晗昱
2023-03-14
问题内容

Java ArrayList<T>(可能还有许多其他类)内部发生的事情是有一个内部对象Object[] array = new Object[n];T对象被写入其中。每当从元素中读取元素时,return (T) array[i];都会进行转换。因此,每次读取时都要进行转换。

我不知道为什么要这样做。对我来说,似乎他们只是在做不必要的演员。只创建一个T[] array = (T[]) new Object[n];,然后不进行强制转换,是否更合乎逻辑,并且速度稍快一些return array[i];?每次阵列创建仅一次强制转换,通常
少于读取次数。

为什么首选他们的方法?我看不出为什么我的想法并不严格吗?


问题答案:

比这还复杂的多:泛型以字节码删除,而的擦除T[]Object[]。同样,的返回get()变为Object。为了保持类型系统的完整性,在实际使用该类时即插入一个选中的强制类型转换,即

Integer i = list.get(0);

将被删除到

Integer i = (Integer) list.get(0);

在这种情况下,ArrayList中的任何类型检查都是多余的。但这确实不重要,因为(T)(T[])都是 未经检查的
强制转换,并且不会产生运行时开销。

可以编写一个检查的ArrayList来执行以下操作:

T[] array = Array.newInstance(tClass, n);

这样可以防止 堆污染
,但要以冗余类型检查为代价(您不能抑制调用代码中的合成强制转换)。它还将要求调用者向ArrayList提供元素类型的类对象,这会使其api变得混乱,并使其更难在通用代码中使用。

编辑:为什么禁止通用数组创建?

一个问题是数组被检查,而泛型未被检查。那是:

Object[] array = new String[1];
array[0] = 1; // throws ArrayStoreException

ArrayList list = new ArrayList<String>();
list.add(1); // causes heap pollution

因此,数组的组件类型很重要。我认为这就是为什么Java语言的设计师要求我们明确使用哪种组件类型。



 类似资料:
  • 本文向大家介绍Swift使用map(_ :)转换数组的元素,包括了Swift使用map(_ :)转换数组的元素的使用技巧和注意事项,需要的朋友参考一下 示例 如Array符合SequenceType,我们可以使用map(_:)转化的阵列A到阵列B使用类型的封闭(A) throws -> B。 例如,我们可以使用它将Ints数组转换为s数组,String如下所示: map(_:)将遍历数组,将给定的

  • 转换/展平列表的简单方法是什么 我知道我可以通过迭代并使用来做到这一点,但我想知道是否有更简单的方法使用Java8个流来做到这一点? 可能是这样的,但不必将原语char装箱到Character:

  • 问题内容: 是否有一种优雅,麻木的方式逐点应用点积?或者如何将以下代码转换为更好的版本? 提前致谢! 问题答案: 方法1 使用- 涉及的步骤: 保持输入的第一个轴对齐。 在减少总和中使最后一个轴相对于第二个轴丢失。 让其余的轴以外积方式从元素展开并 展开 /扩展。 方法#2 如果您正在寻找性能并且求和轴的长度较小,那么最好使用单循环并使用with ,例如- 方法#3 现在,可以将其有效地用于2D输