将 Comparable 与 Comparator 相互转换?

Sky*_*ker 5 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);
            }
        };
    }
Run Code Online (Sandbox Code Playgroud)

Tho*_*MIN 6

您可以获得 Comparator 的实例,该实例能够简单地与 Comparable 类型的实例进行比较

java.util.Comparator.naturalOrder()
Run Code Online (Sandbox Code Playgroud)

请参阅Comparator.naturalOrder()

这是一种从 Comparable 到 Comparator 的转换


Tom*_*icz 4

ComparableComparator来自 Apache Commons Collections 的代码似乎可以解决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;
    }
}
Run Code Online (Sandbox Code Playgroud)

假设你有一个类,但你Foo没有。你像这样使用它:Comparable<Foo>Comparator<Foo>

Comparable<Foo> comparable = new ComparableFromComparator<Foo>(foo, comparator);
Run Code Online (Sandbox Code Playgroud)

正如你所看到的(特别是没有 mixin),它非常丑陋(而且我什至不确定它是否会工作......)还要注意,它不comparable扩展Foo,你必须调用.getInstance()