如何解决为什么 List#indexOf 在没有元素匹配时返回 -1...?
最近,我在阅读 Java Collections Framework 的源代码并注意到 List#indexOf 方法。
在此方法的 Javadoc 中,它说“Returns the index of the first occurrence of the specified element in this list,or -1 if this list does not contain the element.
”
我很好奇为什么它应该精确地返回-1...只需返回一个负数就足以满足要求,以下是我的观点:
- 比较一个数是否为负比比较一个数是否为-1容易。
(判断一个数是否为负数只能比较符号位) - 如果允许为“未找到元素”返回负值,它可能对优化某些特殊数据结构很有用。
我在 Google 和 SO 上搜索过,但似乎没有人跟我一样困惑...
感谢您的回答 :),我是 Java 和 SO 的菜鸟...
解决方法
该方法必须返回一些否则无效的值。可选项在编写这些 API 时并不存在,因此它必须位于有效 int
值的空间内。
否则永远不会出现负值,因此该值必须为负。
这是不容易出错,如果它返回比“任何”(Comparator
/ Comparable
,我看你)一个特定的,否则,无效的值。
但为什么特别是-1?几乎可以肯定是因为他们复制了 String.indexOf
的行为,后者复制了 C++ 中 string::find
的行为,如果未找到,则返回 string::npos
,whose value is -1。
在设计 Java 时,对该语言进行了一些调整以使其对 C++ 程序员“更熟悉”,以鼓励他们尝试;像这样的小事情意味着您不必努力学习完全不同的语义。
为什么 C++ 设计者会选择这个值? ......这可能会持续一段时间。最终,他们需要一个值,并选择了一个可接受的值。
程序员应该努力争取懒惰:考虑到在制定新约定和使用已经存在的东西之间做出选择,后者通常是更好的选择,除非有真的很好的理由不这样做。
,比较一个数是否为负比比较一个数是否为-1容易
你是从错误的“方面”考虑的。考虑 Postel 定律:
在接受的方面保持自由,在发送的方面保持保守。
并将其应用于 API 设计。
你可以自由写作:
if (list.indexOf(something) < 0) ....
哪个有效,每次,因为 -1
是一个负数。
将 API 编写为“任何负数”有什么可能的点?
让我们通过它:
-
它在文件中建议 API 的用户应该编写
< 0
而不是!= -1
- 但这不是一个争论:充其量你可以说文档可以说虽然总是返回 -1,但 API 的用户应该使用< 0
进行检查。除了这很荒谬:检查的正确方法是根本不要调用indexOf
而是调用.contains()
。 -
它可以更容易编写的代码,呼叫
.indexOf
。的这是假强> - 你可以写< 0
一样的。在需要索引稳定的地方,这可能会发生(假设您将一些数据存储在java.util.Map<Integer,X>
集合中,并且您的过程是在列表中查找某个键以找出 id(整数) ),然后映射它,并且您还需要将“未找到的密钥”映射到某些东西。如果指定.indexOf()
返回任何负数以表示未找到,则您必须“清理”它数据为 -1,但您不必这样做,它保证为 -1。 -
这使得它更容易编写的实施方式
java.util.List
。这似乎是一个无聊的论点(你多久实现一次 j.u.List?不完全是每天都会发生,不像调用它)。我相当怀疑它实际上会导致更短的代码,而且我真的怀疑代码会更具可读性。
那么,有什么可能的点?
请记住,这是一个 API 规范。除了“我们需要一些特定的东西”之外,并非每个决定都需要解释,因为 API 的目的是制定通用规则集。有时只要选择任何东西就是主要的胜利,而选择许多相同的选择中的哪一个并不重要。只要每个人都同意使用相同的选择,就可以了。”这就解释了为什么它是 -1 而不是 -100 或 Integer.MIN_VALUE
(-2^31)。他们本可以选择那个。他们没有。 -1 稍微简单一些(写 -1
比 Integer.MIN_VALUE 简单,它是“第一个”负值,它有点符合既定约定,例如各种返回 -1 表示未找到的 C 库。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。