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

他们为什么决定使界面具有“可选操作”

宋斌
2023-03-14
问题内容

ImmutableSet实现Set接口。对于而言,没有意义的ImmutableSet功能现在称为的“可选操作”
Set。我认为这种情况。因此,ImmutableSet现在引发了UnsupportedOperationException许多可选操作。

这对我来说似乎是倒退。我被告知接口是一种契约,因此您可以在不同的实现中使用强制功能。可选操作的方法似乎从根本上改变(矛盾?)接口的作用。今天实现这一点,我会将Set接口分为两个接口:一个接口用于不可变的操作,第二个接口用于扩展器的那些操作。(很快,袖带解决方案)

我了解技术在发生变化。我并不是说 应该
以一种或另一种方式来完成。我的问题是,这种变化是否反映了Java某些基本哲学的变化?使事物向后兼容仅仅是一种创可贴?我对接口是否有不完整的理解?


问题答案:

在Java集合API设计常见问题解答详细介绍这个问题:

问:为什么不直接在核心集合接口中支持不变性,以便可以取消可选操作(和UnsupportedOperationException)?

答:这是整个API中最具争议的设计决策。显然,非常需要静态(编译时)类型检查,这是Java中的规范。如果我们认为它是可行的,我们将予以支持。不幸的是,试图实现此目标的尝试会导致接口层次结构的爆炸式增长,并且无法成功消除对运行时异常的需求(尽管它们大大减少了运行时异常)。

道格·李(Doug Lea)编写了一个流行的Java
Collections程序包,该程序包确实反映了其接口层次结构中的可变性区别,但基于用户对其collections程序包的体验,他不再认为这是一种可行的方法。用他的话(来自个人通信)“让我很难说的是,强静态类型不适用于Java中的集合接口。”

为了详细说明问题,假设您想在层次结构中添加可修改性的概念。您需要四个新接口:ModifiableCollection,ModifiableSet,ModifiableList和ModifiableMap。以前简单的层次结构现在变成了混乱的层次结构。另外,您需要一个新的Iterator接口以用于不可修改的Collection,其中不包含remove操作。现在您可以取消UnsupportedOperationException吗?不幸的是没有。

考虑数组。它们执行大多数List操作,但不执行删除和添加操作。它们是“固定大小”列表。如果要在层次结构中捕获此概念,则必须添加两个新接口:VariableSizeList和VariableSizeMap。您不必添加VariableSizeCollection和VariableSizeSet,因为它们与ModifiableCollection和ModifiableSet相同,但是出于一致性考虑,您可能仍选择添加它们。另外,您还需要各种不支持添加和删除操作的ListIterator以及无法修改的List。现在,我们有多达十个或十二个接口,外加两个新的Iterator接口,而不是原来的四个。我们完了吗?没有。

考虑日志(例如错误日志,审核日志和可恢复数据对象的日志)。它们是自然的仅追加序列,支持所有列表操作(除去和设置(替换))。他们需要一个新的核心接口和一个新的迭代器。

与不可变集合相比,不可变集合又如何呢?(即,客户端无法更改的集合,并且由于其他任何原因也不会更改)。许多人认为这是最重要的区别,因为它允许多个线程同时访问集合而无需同步。将这种支持添加到类型层次结构中还需要四个接口。

现在我们有多达二十个左右的接口和五个迭代器,并且几乎可以肯定的是,实际上仍然存在一些集合,这些集合并不完全适合任何一个接口。例如,Map返回的集合视图是自然的仅删除集合。另外,有些集合会根据其值拒绝某些元素,因此我们仍然没有消除运行时异常。

说完所有内容后,我们认为通过提供很少的一组核心接口(可能会抛出运行时异常)来回避整个问题,这是合理的工程折衷方案。

简而言之,已经进行了Set具有可选操作的接口,以防止所需的不同接口数量呈指数级增长。它不只是“不变”和“可变”那么简单。ImmutableSet然后,番石榴Set必须实现与使用Sets的所有其他代码互操作。这不是理想的方法,但是实际上没有更好的方法。



 类似资料:
  • 问题内容: 我通过文档(去http://java.sun.com/javase/6/docs/api/java/util/Iterator.html)的 存在)被描述成 从基础集合中移除迭代器返回的最后一个元素(可选操作)。每次调用next只能调用一次此方法。如果在迭代进行过程中以其他方式(而不是通过调用此方法)修改了基础集合,则未指定迭代器的行为。 因此,任何人都可以说出“可选”的含义。 这会影

  • 问题内容: 我正在构建一个小型应用程序,并在表之间建立外键关系。但是我对为什么我真的需要这个感到困惑?有什么好处- 在编写不需要执行任何联接的查询时,它对我有帮助吗?这是我的数据库的示例片段: 两者之间存在关键关系。和。 我可以执行这样的查询吗? 既然MySQL应该知道表之间的关系?如果不是,那么外键在数据库设计中的真正功能是什么? 问题答案: 外键提供引用完整性。外键列中的数据经过验证-该值只能

  • 问题内容: 我了解您无法做到,并且了解界面在Go中的工作方式。但是我主要关心的是 为什么 决定接口不能声明字段。 我什至可以看到将其添加到Go V2中的建议。 有人可以对此给出清晰的解释吗? 问题答案: 沃尔克如此准确地在评论中留下了一个原因,他说: “接口仅封装行为。数据不是行为。” 另一个更容易理解的原因是:测试。当前,接口仅指定一组行为。假设我要测试一些需要接口的代码。如果有些脚的开发人员实

  • 问题内容: 有人可以给我一个为什么它不起作用的充分理由: 这将是我建议的(如果不太出色)的解决方案。但这是微不足道的,所以我觉得我很想知道为什么未实现这一点的充分理由。 问题答案: 更新: 条件一致性已在 Swift 4.1中 实现 。 数组和元素的可选元素本身就是 现在,您的代码 可以按照Xcode 9.3的要求进行编译和工作。不再需要解决方法。 (旧答案:) 仅当基础包装类型为等值类型时,才可

  • 问题内容: 当使用Python click库编写命令行界面(CLI)时,是否可以定义三个选项,其中仅当第一个(可选)选项未设置时才需要第二个和第三个选项? 我的用例是一个登录系统,该系统允许我通过(选项1)或通过(选项2)和(选项3)进行身份验证。 如果给出了令牌,则无需检查和定义令牌或提示它们。否则,如果忽略了此令牌,然后和成为必需的,必须给予。 可以使用回调以某种方式完成此操作吗? 我的入门代

  • 目前,我正在使用Cucumber选项和插件来调用自定义报表类实现Reporter。如何在更新的Cucumber 4版本中执行此操作。主要用于获取测试结果,以生成自己的自定义报告。