将Comparable转换为Comparator?

时间:2013-01-14 19:52:44

标签: java

我经常使用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);
            }
        };
    }

5 个答案:

答案 0 :(得分:3)

来自Apache Commons Collections的

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

Comparator.naturalOrder()

这是一种从 Comparable 到 Comparator 的转换

答案 4 :(得分:0)

我认为你不能真正在它们之间进行转换,也不会真正有意义,因为Comarable是类本身的属性,而Comparator是一个外部类。

最好的办法是编写某种包含底层比较逻辑的实用程序类(并且可能具有该实现Comparator),然后将该类用作{{1}的逻辑的一部分在类本身上实现。