我有以下课程.
class MyClass<T>
Run Code Online (Sandbox Code Playgroud)
它使用以下构造函数.
MyClass(Comparator<T> comparator, Collection<? extends T> data)
Run Code Online (Sandbox Code Playgroud)
它有一个在构造函数中设置的字段,如下所示:
this.data = Collections.unmodifiableCollection(data);
Run Code Online (Sandbox Code Playgroud)
在T实现Comparable的特殊情况下,我不想要传入比较器,因为我可以使用自然顺序.所以我认为我应该能够使用这个构造函数:
public <T extends Comparable<T>> MyClass(Collection<T> data)
Run Code Online (Sandbox Code Playgroud)
但显然存在类型不匹配:无法Collection<T> to Collection<? extends T>
在上面的赋值语句中转换.我尝试了各种各样的事情:添加更多通用参数,等等,但都没有工作.我似乎无法指定一个绑定说:如果你有一个实现Comparable的类型T,那就做一些简单的事情吧.
有任何想法吗?
谢谢.
不幸的是,我认为这种“if Comparable do this else do that”的逻辑在 Java 类型系统中是不可能的。
您可以将可比较和不可比较的情况拆分为单独的类并将它们隐藏在接口后面,如下所示:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
但这可能会导致大量重复代码。另一种选择是让 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);
}
}
Run Code Online (Sandbox Code Playgroud)