3

我经常有一个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);
            }
        };
    }
4

5 回答 5

3

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;
    }
}

说你有课FooComparable<Foo>但你有Comparator<Foo>。你像这样使用它:

Comparable<Foo> comparable = new ComparableFromComparator<Foo>(foo, comparator);

正如您所看到的(尤其是没有 mixins),它非常丑陋(而且我什至不确定它是否会工作......)另外请注意,comparable它不会 extend Foo,您必须调用.getInstance()

于 2013-01-14T20:04:44.773 回答
3

自 Java 8 以来,该Comparator接口添加了一些实用程序默认方法,这些方法有助于从可比较对象中派生比较器。

考虑以下按名字对用户进行排序的示例。

class Person {
    String firstName;
    String lastName;
}

List<Person> people = ...
people.sort(Comparator.comparing(Person::firstName));
于 2016-07-19T00:26:31.243 回答
1

可比较的项目可以排序,因为它们有compareTo

Collection<Comparable> items;
Collections.sort(items);

如果项目不是Comparable,它们需要一个 Comparator 对象来进行比较:

Collections<T> items;
Collections.sort(items, comparator);

桥接比较器是微不足道的,你已经做到了。

T item用一些具有 Comparator 的 Comparable 适配器包装每一个,似乎没用。首先不是继承,而是作为字段需要包装项目。

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);
    }
}

开销太大。

于 2013-01-14T20:11:36.253 回答
1

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

java.util.Comparator.naturalOrder()

Comparator.naturalOrder()

这是一种从 Comparable 到 Comparator 的转换

于 2021-07-08T17:10:54.377 回答
0

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

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

于 2013-01-14T20:05:36.860 回答