有没有办法创建一个实现Comparator的类,只允许创建一个单例实例,或者每个参数化类型只有一个实例失败?
我尝试了几种机制(使用私有构造函数然后使用getInstance方法)但两种机制都不是有效的语法。所以我想知道类型擦除是否意味着不可能依赖于通用Comparator类的单个实例。
目的是避免拥有该类的几十个实例,因为所有实例的行为都相同,因此唯一的实例似乎是可取的。可能吗?如果没有,建议的方法是避免比较器实例的疯狂重复?
编辑:这个问题似乎引起了我正在努力实现的困惑,所以我会在这里粘贴我的一个破坏的尝试。下面的代码是尝试创建一个Map,它只为每个类型T保存一个Comparator实例。这是有效的语法,但我无法调用getInstance
方法,因为我无法获取客户端代码中的Class<T>
实例。
final class IntervalComparator<T extends Comparable<T>> implements
Comparator<Interval<T>> {
// Private constructor. Use the getInstance method instead.
private IntervalComparator() {
}
// Map to hold one instance for each type.
private static Map<Class, IntervalComparator> cacheMap = new HashMap<>();
// The only method which returns an instance of this Comparator.
public static <K extends Comparable<K>> IntervalComparator<K>
getInstance(Class<K> type) {
IntervalComparator<K> soleInstance = cacheMap.get(type);
if(soleInstance == null) {
soleInstance = new IntervalComparator<>();
cacheMap.put(type, soleInstance);
}
return soleInstance;
}
@Override
public int compare(Interval<T> o1, Interval<T> o2) {
// ... Comparison code goes here ...
}
}
客户端代码如下所示:
private Set<Interval<T>> intervalSet;
private IntervalUnion(IntervalUnion.Builder<T> builder) {
this.intervalSet = new TreeSet<>(new IntervalComparator<T>());
// ... add Interval<T> objects into intervalSet ...
}
目前每次调用它时都会创建一个new IntervalComparator<T>
对象,我认为没有办法将Class<T>
传递给getInstance
方法。
答案 0 :(得分:1)
我相信你可以使用一个比较器对象。
我假设您的比较器实现IntervalComparator
是无状态的(在某种意义上它没有存储任何字段)。在这种情况下,您始终可以使用相同的代码进行比较。
final class IntervalComparator<T extends Comparable<T>> implements
Comparator<Interval<T>> {
// Private constructor. Use the getInstance method instead.
private IntervalComparator() {
}
private static IntervalComparator INSTANCE = new IntervalComparator();
@SuppressWarnings("unchecked")
public static <K extends Comparable<K>> IntervalComparator<K> getInstance() {
return (IntervalComparator<K>)INSTANCE;
}
@Override
public int compare(Interval<T> o1, Interval<T> o2) {
// ... Comparison code goes here ...
}
}
您的使用案例如下:
private Set<Interval<T>> intervalSet;
private IntervalUnion() {
this.intervalSet =
new TreeSet<Interval<T>>(
IntervalComparator.<T>getInstance());
// ... add Interval<T> objects into intervalSet ...
}
请注意,多态@SuppressWarnings("unchecked")
方法中有一个注释getInstance()
。这是为了压制编译器警告,由于Java泛型中的type erasure,无法检查方法中出现的强制转换。
顺便说一下,这种实施有一个突出的有说服力的先例。方法java.util.Collections.emptyList()
同样实现:
@SuppressWarnings("unchecked")
public static final List EMPTY_LIST = new EmptyList<>();
// ...
@SuppressWarnings("unchecked")
public static final <T> List<T> emptyList() {
return (List<T>) EMPTY_LIST;
}
(参见http://www.docjar.com/html/api/java/util/Collections.java.html#3161)