集合接口与数组

2022-08-31 22:28:05

我们正在了解集合界面,我想知道你们是否都对它的一般用途有什么好的建议?对于不能对数组执行的操作,可以对集合执行哪些操作?对于不能对集合执行的操作(除了允许重复项之外),您可以对数组执行哪些操作?


答案 1

想到它的简单方法是:集合以每种方式都击败了对象数组。考虑:

  • 集合可以是可变的,也可以是不可变的。非空数组必须始终是可变的。
  • 集合可以是线程安全的;甚至并发。数组发布到多个线程从来都不是安全的。
  • 集合可以允许或禁止空元素。数组必须始终允许空元素。
  • 集合是类型安全的;数组不是。因为数组“假”协方差,可以在运行时产生。ArrayStoreException
  • 集合可以包含不可重用的类型(例如 或 )。数组将为此生成警告。List<Class<? extends E>>List<Optional<T>>
  • 集合具有成熟的API;数组只有 set-at-index、get-at-index、length 和 clone。
  • 集合可以具有视图(不可修改,子列表...)。对于数组来说没有这样的运气。
  • 列表或集合的 和方法可以满足用户的期望;在数组上,它们是错误的常见来源。equalshashCodetoString
  • 像类型使用的注释与数组非常混乱 - 很快,这意味着什么?(你是积极的吗?@NullableString @Nullable []
  • 由于上述所有原因,第三方实用程序库不应该费心为数组添加太多额外的支持,只关注集合,所以你也有网络效应。对象数组永远不会成为 Java API 中的一等公民。

上述几个原因在 Effective Java, Third Edition, Item 28 中已经介绍过了,但更详细,从第 126 页开始。

那么,为什么要使用对象数组呢?

  • 你正在非常严格地优化一些东西
  • 您必须与使用它们的API进行交互,并且无法修复它
    • 因此,请尽可能转换为/从该API转换为/从该APIList
  • 因为 varargs (但 varargs 被过度使用)
    • 所以。。。与上一篇相同
  • 我想不出任何其他原因,他们很糟糕

答案 2

这基本上是一个期望的抽象层次的问题。

大多数集合都可以在数组方面实现,但是为了您的方便,它们提供了更多的方法。例如,我所知道的大多数集合实现都可以根据需要进行增长和收缩,或者执行基本阵列无法执行的其他“高级”操作。

例如,假设您正在从文件加载字符串。您不知道文件包含多少换行字符,因此您不知道在分配数组时要使用什么大小。因此,ArrayList 是更好的选择。