为什么Java的TreeSet删除(对象)不接受E
从 Java 6 TreeSet< ;E>
文档:
boolean remove(Object o):
Removes the specified element from this set if it is present.
为什么它接受对象而不是通用类型 E?唯一可以添加的对象是 E 类型,因此唯一可移除的类型应该是 E 类型。
From the Java 6 TreeSet<E>
Documentation:
boolean remove(Object o):
Removes the specified element from this set if it is present.
Why does this accept an Object instead of the generic type E? The only objects that can be added are of type E, so it follows that the only removable type should be of type E.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
从发布的第一条评论中得到答案:
神话:
真实原因:
在这里阅读更多内容: 为什么 Set.contains() 接受一个对象,不是 E?
Taking the answer from the first comment posted:
Myth:
Real reason:
Read more here: Why does Set.contains() take an Object, not an E?
remove()
与get()
一样,在给定 equal 元素时需要工作(就.equals()< /代码>)。在 Java 中,不同类的对象有可能(并且在某些情况下是必需的)相等。因此,您不应该限制类型。
remove()
, likeget()
is required to work when given an equal element (in terms of.equals()
). In Java, it is possible (and in some cases, required) for objects of different classes to be equal. Hence, you shouldn't restrict the type.好吧,每个 E 也是一个对象,也许您现在拥有的 E 不是 E(例如来自事件源),这对您来说很方便。否则,您只需将其强制转换为 E 即可将其删除。
从相等的角度来看,这并不重要:将测试给定对象的引用地址是否等于集合的内容,因此它属于哪个类并不重要。
Well, each E is also an Object, and perhaps you have the E not as E at the moment (e.g from an Event source), which makes it convenient for you. Otherwise you just have to cast it to E only to remove it.
From an equality point of view this doesn't matter: The given object's reference address is tested if it equals a set's content, so it doesn't matter of which class it is.
这确实是一个问题。如果有人调用
remove(o)
并且o
的类型不是E
,这通常是一个编程错误,试图删除错误的东西。类型检查未能保护我们免受错误的影响。尽管一个好的 IDE (IntelliJ) 可以检测到此类问题并向我们发出警告,但 API 设计者应该提供更精确的签名来利用编译器类型检查。 (IDE 在这里作弊 - 它知道
Set.remove()
的含义,因为它是标准 API。IDE 不会为自定义 API 提供相同的帮助)对于像
contains()< 这样的查询 API /code>,接受非
E
参数并返回一个简单的 false 是可以的。因此,我们可以同时拥有像
remove()
这样的 Formutation API,但它是否应该接受非E
参数是有争议的。然而,考虑到删除的现实,这场辩论将毫无意义——除了接受非 E 论点并对此保持沉默之外,我们别无选择。我们仍然可以有两个方法。在大多数情况下,程序员可以调用contains2/remove2 来获得额外的类型安全性。
This is indeed a problem. If someone calls
remove(o)
ando
's type is notE
, it is usually a programming bug that tries to remove the wrong thing. Type checking failed to protect us from the bug.Although a good IDE (IntelliJ) can detect such issues and warn us, API designers should have provided more precise signature to utilize compiler type checking. (IDE cheats here - it knows the meaning of
Set.remove()
because it's a standard API. IDE will not provide the same help for custom APIs)For query API like
contains()
, it is OK to accept a non-E
argument and return a trivial false. So we can have bothFor mutation API like
remove()
, it's debatable whether it should accept a non-E
argument. However the debate is going to be moot, given the reality of erasure - there is really no choice but accept non-E argument and be silent about it. Still we can have two methodsIn most cases, programmers can call
contains2/remove2
for extra type safety.