我经常使用Comparator
类型,而我需要Comparable
,反之亦然。是否有可重用的JDK API可以相互转换?有点像:
public static <C> Comparable<C> toComparable(final Comparator<C> comparator) {
// does not compile because Hidden can not extend C,
// but just to illustrate the idea
final class Hidden extends C implements Comparable<C> {
@Override
public int compareTo(C another) {
return comparator.compare((C) this, another);
}
};
return new Hidden();
}
public static <C extends Comparable<C>> Comparator<C> toComparator(final Class<C> comparableClass) {
return new Comparator<C>() {
@Override
public int compare(C first, C second) {
assert comparableClass.equals(first.getClass());
assert comparableClass.equals(second.getClass());
return first.compareTo(second);
}
};
}
答案 0 :(得分:3)
ComparableComparator
似乎解决了Comparable<T>
到Comparator
问题(不幸的是它不是通用类型友好的)。
反向操作不太可能,因为Comparator<T>
表示算法,而Comparable<T>
表示实际数据。你需要某种组合。快速而肮脏的解决方案:
class ComparableFromComparator<T> implements Comparable<T> {
private final Comparator<T> comparator;
private final T instance;
public ComparableFromComparator(Comparator<T> comparator, T instance) {
this.comparator = comparator;
this.instance = instance;
}
@Override
public int compareTo(T o) {
return comparator.compare(instance, o);
}
public T getInstance() {
return instance;
}
}
假设您的课程Foo
不是Comparable<Foo>
,而是Comparator<Foo>
。你这样使用它:
Comparable<Foo> comparable = new ComparableFromComparator<Foo>(foo, comparator);
正如你所看到的(特别是没有mixins)它非常难看(我甚至不确定它是否会起作用......)另请注意comparable
不会延伸Foo
,你必须改为呼叫.getInstance()
。
答案 1 :(得分:2)
从Java 8开始,Comparator
接口添加了一些实用程序默认方法,可以帮助从可比较的方法中导出比较器。
考虑以下按名字排序用户的示例。
class Person {
String firstName;
String lastName;
}
List<Person> people = ...
people.sort(Comparator.comparing(Person::firstName));
答案 2 :(得分:1)
可比较的项目可以按compareTo
:
Collection<Comparable> items;
Collections.sort(items);
如果项目不可比较,则需要使用Comparator对象进行比较:
Collections<T> items;
Collections.sort(items, comparator);
桥接比较器很简单,你已经做到了。
使用具有比较器的某个Comparable适配器包装每个T item
似乎没用。
首先不是继承,但是当字段需要包装项目时。
public class CatorComparable<T> implements Comparable<CatorComparable<T>> {
public T value;
private Comparator<T> cator;
public CatorComparable(T value, Comparator<T> cator) {
this.value = value;
this.cator = cator;
}
@Override
public int compareTo(CatorComparable<T> other) {
return cator.compareTo(value, other.value);
}
}
太多开销。
答案 3 :(得分:1)
您可以获得一个 Comparator 实例,可以简单地将 Comparable 类型的实例与
进行比较pw.prn
这是一种从 Comparable 到 Comparator 的转换
答案 4 :(得分:0)
我认为你不能真正在它们之间进行转换,也不会真正有意义,因为Comarable
是类本身的属性,而Comparator
是一个外部类。
最好的办法是编写某种包含底层比较逻辑的实用程序类(并且可能具有该实现Comparator
),然后将该类用作{{1}的逻辑的一部分在类本身上实现。