java映射:为Integer和Double类型定义一个方法,而不是String
我正在尝试为我的新Map
类定义一个方法putIfGreaterThan()
(给定一个键,只有当新值大于旧值时,它才会用新值替换旧值)
我知道我可以通过组合(在新类中有一个private final Map<String, Double> map;
,然后将一个Map
传递给构造函数)或者在我的新类中实现Map
接口,然后将一个Map
传递给构造函数来实现这一点(尽管我不确定哪种方法更好)
我的主要问题是,我需要能够在<String, Double>
和<String, Integer>
上调用方法putIfGreaterThan()
,但不能在<String, String>
上调用(因为在<String, String>
上调用它没有意义)。如果我使用泛型(<K, V>
),客户端可以传递一个不允许的<String, String>
。另一方面,如果我允许Double
,我将无法通过Integer
,反之亦然。如何定义一个允许整数或双精度但不允许字符串的方法
注意:我无法定义两个构造函数(一个用于Double,一个用于Integer),因为我得到了错误:方法XX的擦除与类型XX中的另一个方法相同
# 1 楼答案
您可以使用decorator模式并将泛型限制为
Number
的子类型,您可以使用this answer中的一个小技巧在不强制转换的情况下进行比较。它采用数字实例的字符串表示,并创建一个BigDecimal
实例,从而避免任何类型的强制转换下面是decorator的相关实现细节,当然您需要覆盖
Map
接口的其余方法您可以随意禁止
Number
的其他子类型,也就是抛出一个异常,这是您认为合适的# 2 楼答案
不幸的是,泛型和数字不能很好地结合在一起。但你可以这样做:
# 3 楼答案
理想情况下,您应该声明一个引入类型参数的方法,该类型参数为
extends V & Comparable<? super V>
,但这不是有效的Java但是,您可以定义静态方法而不使用
&
如果使用不同的构造,那么对于
V
是Comparable<? super V>
的情况,类型需要不同。如果两个构造函数具有相同的擦除,那么可能是时候有意义地命名静态创建方法了