[英]T extends Comparable<T>
I have the following class. 我有以下课程。
class MyClass<T>
It uses the following constructor. 它使用以下构造函数。
MyClass(Comparator<T> comparator, Collection<? extends T> data)
And it has a field which is set in the constructor like so: 它有一个在构造函数中设置的字段,如下所示:
this.data = Collections.unmodifiableCollection(data);
In the special case where T implements Comparable, I don't want to require that a comparator be passed in, since I can just use the natural ordering. 在T实现Comparable的特殊情况下,我不想要传入比较器,因为我可以使用自然顺序。 So I thought I should be able to use this constructor:
所以我认为我应该能够使用这个构造函数:
public <T extends Comparable<T>> MyClass(Collection<T> data)
But there is apparently a type mismatch: cannot convert from Collection<T> to Collection<? extends T>
但显然存在类型不匹配:无法从
Collection<T> to Collection<? extends T>
转换Collection<T> to Collection<? extends T>
Collection<T> to Collection<? extends T>
in the assignment statement above. 在上面的赋值语句中
Collection<T> to Collection<? extends T>
。 I've tried all sorts of things: adding more generic parameters, and so on, but none work. 我尝试了各种各样的事情:添加更多通用参数,等等,但都没有工作。 I seem unable to specify a bound that says: if you have a type T that implements Comparable, do the straightforward thing.
我似乎无法指定一个绑定说:如果你有一个实现Comparable的类型T,那就做一些简单的事情吧。
Any ideas? 有任何想法吗?
Thanks. 谢谢。
Unfortunately I don't think this kind of "if Comparable do this else do that" logic is possible with the Java type system. 不幸的是,我不认为这种“如果可比较做其他事情那样”逻辑是可能的Java类型系统。
You could split the Comparable and non-Comparable cases into separate classes and hide them behind an interface, something like this: 您可以将Comparable和Non-Comparable案例拆分为单独的类并将它们隐藏在接口后面,如下所示:
interface Interface<T> {
public void processData();
}
class MyClass<T> implements Interface<T> {
private final Collection<? extends T> data;
MyClass(Comparator<T> comparator, Collection<? extends T> data) {
this.data = data;
}
public void processData() {
// ...
}
}
class MyCompClass<T extends Comparable<T>> implements Interface<T> {
private final Collection<? extends T> data;
MyCompClass(Collection<? extends T> data) {
this.data = data;
}
public void processData() {
// ...
}
}
class Factory {
static <T extends Comparable<T>> Interface<T> create(Collection<? extends T> data) {
return new MyCompClass<T>(data);
}
static <T> Interface<T> create(Comparator<T> comparator, Collection<? extends T> data) {
return new MyClass<T>(comparator, data);
}
}
But this might result in a lot of duplicated code. 但这可能会导致大量重复的代码。 Another option is to leave MyClass requiring a Comparator in its constructor, and build that comparator in the factory:
另一种选择是让MyClass在其构造函数中需要Comparator,并在工厂中构建该比较器:
class MyClass<T> {
private final Collection<? extends T> data;
MyClass(Comparator<T> comparator, Collection<? extends T> data) {
this.data = data;
}
public void processData() {
// ...
}
}
class Factory {
static <T extends Comparable<T>> MyClass<T> create(Collection<? extends T> data) {
return new MyClass<T>(new Comparator<T>() {
public int compare(T o1, T o2) {
return o1.compareTo(o2);
}
}, data);
}
static <T> MyClass<T> create(Comparator<T> comparator, Collection<? extends T> data) {
return new MyClass<T>(comparator, data);
}
}
I concur this appears to be impossible, as the straightforward solution 我同意这似乎是不可能的,因为直截了当的解决方案
class MyClass<T> {
Collection<? extends T> data;
public MyClass(Comparator<T> comparator, Collection<? extends T> data) {
this.data = data;
}
public <E extends T & Comparable<T>> MyClass(Collection<E> data) {
this.data = data;
}
}
is rejected by the compiler with 被编译器拒绝
Cannot specify any additional bound
Comparable<T>
when first bound is a type parameter当第一个绑定是类型参数时,无法指定任何其他绑定的
Comparable<T>
See also Why can't I use a type argument in a type parameter with multiple bounds? 另请参见为什么我不能在具有多个边界的类型参数中使用类型参数? (in particular Chris Povirk's answer).
(特别是Chris Povirk的回答)。
As for solutions, I agree with Chris B. 至于解决方案,我同意Chris B.
You can use the regular constructor for the first case and a factory method for the second one: 您可以将常规构造函数用于第一种情况,将工厂方法用于第二种情况:
class MyClass<T> {
Collection<? extends T> data;
Comparator<? super T> comparator;
public MyClass(Comparator<? super T> comparator, Collection<? extends T> data) {
this.data = data;
this.comparator = comparator;
}
public static <T extends Comparable<? super T>> MyClass<T> fromComparable(Collection<T> data) {
return new MyClass<T>(Collections.reverseOrder(Collections.reverseOrder()), data);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.