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

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

FooではないクラスがあるとしますがComparable<Foo>、 は持っていますComparator<Foo>。次のように使用します。

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

ご覧のとおり (特に mixinを使用しない場合)、かなり醜いです (そして、それが機能するかどうかさえわかりません... comparable) 。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);

ブリッジング Comparator は自明であり、既に実行済みです。

T itemComparator を持つ 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 に答える
0

Comarableはクラス自体のプロパティでありComparator、外部クラスである ため、それらの間で実際に変換できるとは思いません。また、実際には意味がありません。

最善の策は、基礎となる比較ロジックを含む (そしておそらくその implement を持つ) ある種のユーティリティ クラスを作成し、そのクラスをクラス自体Comparatorの実装のロジックの一部として使用することです。Comparable

于 2013-01-14T20:05:36.860 に答える