为什么Java的TreeSet删除(对象)不接受E

发布于 2024-12-13 21:57:45 字数 342 浏览 0 评论 0原文

从 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

岁月流歌 2024-12-20 21:57:45

从发布的第一条评论中得到答案:

神话:

一个流行的神话是它是愚蠢和邪恶的,但它是
由于向后兼容性,这是必要的。但兼容性
争论是无关紧要的;无论您是否考虑,API 都是正确的
是否兼容。

真实原因:

统一地,Java Collections Framework(以及 Google
集合库也)从不限制其参数的类型
除非有必要防止集合被获取
坏了。

在这里阅读更多内容: 为什么 Set.contains() 接受一个对象,不是 E?

Taking the answer from the first comment posted:

Myth:

A popular myth is that it is stupid and evil, but it was
necessary because of backward compatibility. But the compatibility
argument is irrelevant; the API is correct whether you consider
compatibility or not.

Real reason:

Uniformly, methods of the Java Collections Framework (and the Google
Collections Library too) never restrict the types of their parameters
except when it's necessary to prevent the collection from getting
broken.

Read more here: Why does Set.contains() take an Object, not an E?

小糖芽 2024-12-20 21:57:45

remove()get() 一样,在给定 equal 元素时需要工作(就 .equals()< /代码>)。在 Java 中,不同类的对象有可能(并且在某些情况下是必需的)相等。因此,您不应该限制类型。

remove(), like get() 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.

万劫不复 2024-12-20 21:57:45

好吧,每个 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.

吻安 2024-12-20 21:57:45

这确实是一个问题。如果有人调用 remove(o) 并且 o 的类型不是 E,这通常是一个编程错误,试图删除错误的东西。类型检查未能保护我们免受错误的影响。

尽管一个好的 IDE (IntelliJ) 可以检测到此类问题并向我们发出警告,但 API 设计者应该提供更精确的签名来利用编译器类型检查。 (IDE 在这里作弊 - 它知道 Set.remove() 的含义,因为它是标准 API。IDE 不会为自定义 API 提供相同的帮助)

对于像 contains()< 这样的查询 API /code>,接受非 E 参数并返回一个简单的 false 是可以的。因此,我们可以同时拥有

boolean contains(Object o);
boolean contains2(E o);

remove() 这样的 Formutation API,但它是否应该接受非 E 参数是有争议的。然而,考虑到删除的现实,这场辩论将毫无意义——除了接受非 E 论点并对此保持沉默之外,我们别无选择。我们仍然可以有两个方法

boolean remove(Object o);
boolean remove2(E o);

。在大多数情况下,程序员可以调用contains2/remove2 来获得额外的类型安全性。

This is indeed a problem. If someone calls remove(o) and o's type is not E, 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 both

boolean contains(Object o);
boolean contains2(E o);

For 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 methods

boolean remove(Object o);
boolean remove2(E o);

In most cases, programmers can call contains2/remove2 for extra type safety.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文