Joo*_*o21 0 string collections any kotlin
使用 Any 作为集合类型是否比使用具体类型消耗更少的内存?
\n认为
\nval list1 = listOf<Any>("ABC", "DEF", "GHI", "JKL", "MNO")\nval list2 = listOf<String>("ABC", "DEF", "GHI", "JKL", "MNO")\nRun Code Online (Sandbox Code Playgroud)\n我想知道是否list1消耗的内存比list2类型String分配内存来存储其属性(例如size)要少
list1那么,如果我不使用任何String类型函数,是不是更好?
\n编辑
\n如果我想使用集合中的其他类型怎么办?
list = listOf<Any>("ABC", 123, 12.34)\nRun Code Online (Sandbox Code Playgroud)\n它比效率更高吗
\nlist = listOf<String>("ABC", "123", "12.34")\nRun Code Online (Sandbox Code Playgroud)\n
\n编辑 2
\n感谢@Jo\xc3\xa3o Dias 和@gidds
正如@gidds 所说:
\n\n\n该列表不直接包含 String 对象,或其包含引用的任何对象 \xe2\x80\x94 。
\n
\n\nString 引用的大小与 Any 引用或任何其他类型的引用完全相同。\xe2\x80\x82
\n
因此,由于类型擦除List<String>,和List<Any>是完全相同的- @Jo\xc3\xa3o Dias 指出- 编译时和运行时类型不同\n
但是,这是否意味着
\nval list1 = listOf<Any>("ABC", "DEF", "GHI")\nRun Code Online (Sandbox Code Playgroud)\n和
\nval list2 = listOf<String>("ABC", "DEF", "GHI")\nRun Code Online (Sandbox Code Playgroud)\n消耗相同的内存
\nval list3 = listOf<List<List<List<String>>>>(\nlistOf(listOf(ListOf("ABC"))), \nlistOf(listOf(ListOf("DEF"))), \nlistOf(listOf(ListOf("GHI")))\n)\nRun Code Online (Sandbox Code Playgroud)\nAFAIK,String基本上是 的集合Char。AString包含对 的引用Char。由于 Kotlin 中的所有内容都是对象,因此Char内部的每个对象都String应该包含对堆中值的引用,到目前为止我正确吗?\n如果是这种情况,那么消耗比拥有超过 1 个引用更多的内存
是否有意义。List<String>List<Any>List<String>
到目前为止尚未解决的一点是列表不直接包含String对象,或者它包含引用的Any对象 \xe2\x80\x94 。
引用的String大小与引用或任何其他类型的引用完全相同Any。\xe2\x80\x82(该大小取决于运行代码的 JVM 的内部结构;它可能是 4 或 8 个字节。\xe2\ x80\x82请参阅这些 问题。)
当然,被引用的对象也会在堆中占用自己的空间;但这两种情况都是一样的。
\n编辑添加:
\nList如何实现和的内部细节String与原始问题无关。\xe2\x80\x82(这很好,因为它们在实现之间有所不同。)\xe2\x80\x82JVM 语言(例如 Kotlin)只有两种值:基元(Int、Short、Long、Byte、Char、Double、Float、Boolean)和引用(对象或数组)。
因此,任何集合,如果它不是基元集合,都是引用集合。\xe2\x80\x82这适用于所有List实现。\xe2\x80\x82因此,您的list1和list2对象的大小将完全相同,仅取决于他们持有(或可以持有)的参考文献数量,而不是这些参考文献中的内容。
如果你想要更深入的了解,list1是一个参考,指向一个实现该List接口的对象。\xe2\x80\x82有很多不同的实现,我不知道 Kotlin 会选择哪一个(再说一次,可能会在版本之间发生变化),但比如说它是一个ArrayList.\xe2\x80\x82,它至少有两个属性:一个大小(可能是一个Int)和一个对数组的引用,该数组保存对列表中的项目。\xe2\x80\x82(该数组通常会大于列表的当前大小,这样您就可以添加更多项目,而不必每次都重新分配数组;列表的当前大小数组被称为列表的容量。)\xe2\x80\x82如果这些项是Strings,则确切的内部表示取决于 JVM 版本,但它可能是一个至少具有三个属性的对象Char:一个Int给出数组中字符串的起始索引,另一个Int给出长度。
但正如我所说,随着时间的推移以及 JVM 版本之间的细节会发生变化。\xe2\x80\x82 不变的是,它是引用List的集合,并且引用的大小不依赖于其类型。\ xe2\x80\x82因此,引用列表String(所有其他条件相同)将与对这些相同字符串的引用列表占用完全相同的空间Any。
(而且,正如其他地方提到的,由于运行时的类型擦除,JVM 没有类型参数的概念,因此对象实际上是相同的。)
\n当然,\xe2\x80\x98深度大小\xe2\x80\x99(列表及其包含的对象占用的总堆空间)将取决于这些对象\xe2\x80\x94的大小,但在在我们正在讨论的情况下,这些是完全相同的String对象,因此大小也没有差异。
| 归档时间: |
|
| 查看次数: |
246 次 |
| 最近记录: |