扩展我的部门私有Libary我试图实现一个isBetween方法。此方法是通用的,并且期望Comparable
类型T
表示其最小值,最大值以及varargs值。其目的是检查所有值是否在指定范围内。
public static void main(String[] args) {
System.out.print(isBetween(1, 100, 200, 100, 1, 2));
}
@SafeVarargs
public static <T extends Comparable> boolean isBetween(T minimum, T maximum, T... values) {
for (T value : values) {
if (!(value.compareTo(minimum) >= 0 && value.compareTo(maximum) <= 0))
return false;
}
return true;
}
这很好用。但是类型T可以包含任何Comparable对象。方法调用:
System.out.print(isBetween(1, 100, 200, 100, "How awkward", 2));
也将在编译时被接受。 这根本不是类型安全的,不能被接受。
我想到了两个解决方案:
1。按以下方式调用方法
System.out.print(Class.<Integer>isBetween(1, 100, 200, 100, 1, 2));
2。制作U
类型的方法参数之一,并将类型T
扩展为键入U
两种“解决方案”似乎都不是很优雅。第一个需要在调用方法之前编写其他代码,而第二个代码似乎是一个黑客。
有没有更优雅的方法来解决我的问题?
答案 0 :(得分:3)
嗯,这可以通过avoiding raw types轻松解决。
让我们来看看你的代码:
public static <T extends Comparable> boolean isBetween(T minimum, T maximum, T... values) {
// ...
}
T
是一个很好的通用,但Comparable
是原始类型。您需要Comparable<T>
,因此您的方法应如下所示:
public static <T extends Comparable<T>> boolean isBetween(T minimum, T maximum, T... values) {
// ...
}
然后isBetween(1, 100, 200, 100, "How awkward", 2)
将不再可能。
isBetween
方法允许“相等”参数类型,如果它们具有实现Comparable
的相等超类。
例如,使用java.util.Date
和java.sql.Date
(用户fge有这个好主意):
isBetween(new java.util.Date(1L), new java.util.Date(4L), new java.sql.Date(5L))
这将导致“false”,因为第三个参数比上限更“大”。并且java.sql.Date
被接受,因为它扩展了java.util.Date
并将T
推断为“实现Comparable
的公共父类”。
答案 1 :(得分:1)
将其设为<T extends Comparable<T>>
:
@SafeVarargs
public static <T extends Comparable<T>> boolean isBetween(T minimum, T maximum, T... values) {
for (T value : values) {
if (!(value.compareTo(minimum) >= 0 && value.compareTo(maximum) <= 0))
return false;
}
return true;
}
这将在编译时失败。
答案 2 :(得分:1)
另一种方法是传递Comparator
,而不是要求T
为Comparable
:
public static <T> boolean isBetween(Comparator<? super T> comparator,
T minimum, T maximum, T... values) {
for (T value : values) {
if (!(comparator.compare(value, minimum) >= 0 &&
comparator.compare(value, maximum) <= 0)){
return false;
}
}
return true;
}
这允许您根据需要比较对象,并且它们不需要是Comparable
。
您还可以提供与其他答案类似的方法,以便在Comparator
为T
时跳过写Comparable
:
public static <T extends Comparable<? super T>> boolean isBetween(T minimum,
T maximum, T... values) {
return isBetween(T::compareTo, minimum, maximum, values);
}
答案 3 :(得分:0)
使用Comparable&lt; T>而不是原始的可比较。这样,您将确保T类型的所有实例都具有相同的类型,并且在编译时将失败。