java - `java.util.List.subList()` 到底应该如何工作?

标签 java list

List 通过调用 List.subList(int fromIndex, int到索引)

对实际操作不感兴趣,如在 Oracle JVM 中观察到的那样;我对接口(interface)行为规范很感兴趣,因此可以可靠地实现自己的列表类(这里的可靠性是指能够仅通过实现 java.util.List< 来交换 Javas 列表类之一和自己的列表类)/ 接口(interface))。

documentation of List甲骨文似乎没有阐明上述内容。请注意,这与尝试通过除子列表之外的任何其他方式修改列表无关,这是关于通过子列表进行的修改,确实有文档支持。

示例:

假设我有一个包含 6 个元素的列表 A、B、C、D、E、F。在列表上调用 subList(1, 4) 会得到一个包含元素 B、C、D 的子列表。然后,我在此子列表上调用 remove(D)。我想知道 D 被删除后子列表将包含哪些元素?一些替代方案:

  1. B、C、E(子列表保留原始索引范围)?
  2. B, C(实际上不再是 subList(1, 4))?

我的猜测是,由于子列表是用 subList(1, 4) 指定的,因此列表本身的“窗口”必须具有相同的“大小”,因此 E 可以这么说滑入 View ,因为 View 的结束索引仍然是 4,随着 D 现在已经超出了 E。第二种选择对我来说似乎不是很明智,但仍然是一种选择。

最佳答案

已在 documentation of java.util.AbstractList class 中找到以下可能回答问题的引用规范(有点令人惊讶的是,java.util.List 的文档中):

This implementation returns a list that subclasses AbstractList. The subclass stores, in private fields, the offset of the subList within the backing list, the size of the subList (which can change over its lifetime), and the expected modCount value of the backing list.

从 View 大小可以改变的事实来看,索引也可以改变,这意味着在问题中概述的示例场景中,元素 E不会“滑入 View ”。因此,第二种选择是正确的,因为删除 D 后子列表的大小减 1,此时的子列表包含 2 个元素 B, C .

部分 Java 设计者可能是故意选择AbstractList 中指定上述内容页面,而不是 List 的文档页面- 因此后者保留了歧义。但是,我希望有两个不同的列表类实现 List在这个特定的细节级别上可以轻松交换和兼容。此外,并非每个 List实现将扩展 AbstractList - 这是一种便利,而不是必需的。

这里是从 AbstractList 移动引用的规范(连同一些其他细节)页面到 List文档页面。

关于java - `java.util.List.subList()` 到底应该如何工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15323694/

相关文章:

java - 远程应用服务器部署

python - 如何从字典列表中删除重复项?

c - delete tail 不返回正确的列表

c - 在结构中存储数据(链表)

java - 我应该如何让 AES 处理 Java 中任意长度的字符串?

java - Mongoexport - "\n"问题

java - 从 URL 获取文件的 MD5 哈希值

java - 如何使用 AWS Java SDK 按降序从 DynamoDb 获取项目?

arrays - ballerina - 检查数组中是否存在某个值

java - 二维列表数组的问题