类型安全有效地只读 java 集合?

Posted

技术标签:

【中文标题】类型安全有效地只读 java 集合?【英文标题】:Typesafe effectively read only java collections? 【发布时间】:2021-05-09 02:44:27 【问题描述】:

我正在为没有允许突变的方法的集合搜索 Java 库。有效的不可变只读集合。

我的意思是,没有方法。不像通常的 Java 不可变集合,它们具有像 addremove 这样的方法,在调用时会抛出异常。不...我希望编译器让我知道我正在尝试做一些不允许的事情,而不是在运行时出现一些错误。

我知道它的存在是因为我用过它,但我不记得这个库的名字了。

【问题讨论】:

写一个包装类!但无论你使用什么都不是Collection,因为all Collections 应该声明这些方法,因为它是Collection 接口的一部分 @xtratic 我知道这样的库存在。另外,我的公司不允许我有空间来实施上述包装器。 包装器将无济于事,因为它不会给出编译时错误。 @Horse 如果您制作的包装器仅公开“读取”方法。那么当您尝试使用未公开/未定义的“写入”方法时,它肯定会出现编译错误。跨度> @AlejandroNavas 请在选择集合框架时格外小心,因为如果您的接口/模块将被公司使用,它将产生非常大的影响。此外,多年来某些不兼容的库版本,有些项目已经诉诸于特定版本的阴影。同样不要气馁,但在选择短焦点的集合框架时请格外小心。 【参考方案1】:

Eclipse 收藏:https://www.eclipse.org/collections/

他们自己的guide on immutable collections 说:

Eclipse Collections 中的所有基本容器都具有可变和不可变(不可更改)形式的接口。这与 JCF 模型有些不同,在该模型中,大多数容器都是可变的。

不可变集合就是这样 - 一旦创建,就永远无法修改,在其整个生命周期内保留相同的内部引用和数据。一个不可变集合等于一个对应的具有相同内容的可变集合; MutableListImmutableList 可以相等。

【讨论】:

这个!多谢!这就是我一直在寻找的。我不知道为什么我忘记了名字 如您所见,Guava ImmutableCollection 具有抛出的变异方法。我还查看了 Trove、hppc、fastutil、koloboke 和 Javolution,但都没有提供你想要的。 谢谢@Petr!还是要检查其他库 说了这么多,我自己在我的代码中只使用 Guava 的 ImmutableCollections,因为它们取得了很好的平衡,并且可以与所有现有代码互操作。他们的变异方法也在编译时显示警告,这对我们来说已经足够好了。 Eclipse Collections 虽然非常好,但要求您使用它们,并且尽可能只使用它们。 我将使用 Eclipse 集合,因为我试图让我的团队慢慢获得编程的功能性思维方式。鉴于他们有一种非常迫切的心态,我也不希望在运行时为此抛出一些偷偷摸摸的异常。幸运的是,可变的 eclipse 集合确实实现了 Java 集合层次结构,所以我只需要添加一些 .toMutableList() 或类似的东西,让它与其他库互操作【参考方案2】:

Guava 的immutable collections 使用@Deprecated 声明可变方法,因此使用它们会发出编译器警告。

这可能是两全其美,因为它允许在任何需要 Collection 的地方传递 ImmutableCollection

【讨论】:

老实说,我更喜欢从不可变的 Eclipse 集合中创建一个常用的 java 列表 @meriton, ImmutableCollection 将不保证 OP 所期望的编译时间检查(即使是高级代码扫描器也无法推进抽象实际实例化对象的深度嵌套实现)。这显然需要在与 java Collectioncompile time check 的接口兼容性之间进行权衡。

以上是关于类型安全有效地只读 java 集合?的主要内容,如果未能解决你的问题,请参考以下文章

.NET不可变集合已经正式发布

Java容器集合框架

foreach用法

可变类型的安全性——更锋利的C#代码小记

Java学习笔记29(集合框架三:泛型)

Java -- 每日一问:如何保证集合是线程安全的? ConcurrentHashMap如何实现高效地线程安全?