我正在处理现有代码并遇到以下语法:
HashMap<Comparable<?>, something>
为什么我们将Comparable<?>
作为关键?在什么情况下这将是有用的?
答案 0 :(得分:2)
从输入的角度来看,这意味着HashMap
的键可以是任何实现Comparable
的类型,而不管类型参数如何。
从应用程序的角度来看,根本不清楚这意味着什么。
Comparable的正常用法是这样的。
public class SomeType implements Comparable<SomeType> {
public int compareTo(SomeType other) { ... }
// etcetera
}
换句话说,SomeType
可以与另一个SomeType
进行比较。如果您尝试将SomeType
与其他类型进行比较,那么您会期望ClassCastException
...基于这些类型无法比拟的类型。 (和IIRC,Comparable
的javadocs推荐 compareTo
为无法比拟的类型抛出CCE
...。
那么使用类型为Comparable<?>
的密钥会是什么?您是否期望它与不同类型相媲美?
如果是这样,您如何实施一种compareTo
方法,可以有意义地将this
与任何其他Comparable<?>
进行比较...
如果没有,那么密钥成为Comparable<?>
有什么用呢?你将获得CCE ......
简而言之,我认为这是一个设计错误。我认为最好写一下:
HashMap<T extends Comparable<T>, Something>
答案 1 :(得分:0)
这是一个具体的实现,其中对密钥的唯一限制是实现Comparable接口。使用通配符是为了表明支持Comparable<T>
的任何实现。通配符是必要的,以便不使用原始类型,由于引入了泛型,因此非常不鼓励使用。如果您使用原始类型,您会注意到编译器会立即向您发出警告并建议您转而使用泛型。请注意,Comparable<T>
接口本身就是通用的。
当您想要在按键上应用订单时,此类密钥非常有用。考虑一个您想要对键进行排序的简单场景。如果您使用immutable但不具有可比性的密钥,则无法做到这一点。
答案 2 :(得分:0)
以Comparable<?>
为键,映射定义指定它接受任何Object作为实现Comparable
接口的键。
通常,建议使用通配符Comparable<?>
而不是原始类型Comparable
。描述的原因为here。
从技术上讲,对于HashMap
,在任何情况下强制实施Comparable<?>
密钥都没有用,因为HashMap
内部不会使用compareTo
方法{ {1}}界面。
它将依赖于密钥的Comparable
和equals
实现。