3

こんにちはスタックオーバーフローコミュニティ!私はこれらのフォーラムに不慣れで、Java および Android プログラミングにもかなり慣れていないため、たまたま質問の対象になっています。

私の問題はソートです。選択したフィールドに基づいてオブジェクトをソートする方法を探しています (最初のフィールドに基づいてソートするのではなく、次のフィールドに基づいてソートするのではなく、コンパレータ チェーンによって例示されます)。問題の解決策を見つけたと思います:

https://stackoverflow.com/a/5113108/1549672

しかし、実際にこれを機能させるのに問題があります。Java の経験がないために、おそらく何かが欠けているのではないかと疑っています。

ここに私がしようとしているものがあります:

私のクラスとして-

public class ItemLocation {
String title;
int id;
}

私の機能として-

public void sort(final String field, List<ItemLocation> itemLocationList) {
    Collections.sort(itemLocationList, new Comparator<ItemLocation>() {
        @Override
        public int compare(ItemLocation o1, ItemLocation o2) {
            if(field.equals("title")) {
                return o1.title.compareTo(o2.title);
            } else if(field.equals("id")) {
                return Integer.valueOf(o1.id).compareTo(o2.id);
            }
            return 0;
        }
    });
}

これらを使用して、誰かがこの方法を使用する例を挙げてもらえますか? ArrayList を埋めてソートしようとしましたが、役に立ちませんでした。

助けてくれてありがとう!

4

4 に答える 4

8

それらが等しくない場合0、メソッドから戻るべきではありません。Comparator.compare契約では「オーケー」ですが、APIドキュメントからは正確には推奨されていません:

一般的にはそうですが、厳密には (compare(x, y)==0) == (x.equals(y)) である必要はありません。一般に、この条件に違反するコンパレータは、この事実を明確に示す必要があります。推奨される言語は、「注: このコンパレータは、equals と矛盾する順序付けを課します。」


Comparator私の意見では、代わりに各フィールドに固有のものを返す必要があります。

Comparator<ItemLocation> titleComparator = new Comparator<ItemLocation>() {
    @Override
    public int compare(ItemLocation o1, ItemLocation o2) {
        return o1.title.compareTo(o2.title);
    }
}

Comparator<ItemLocation> idComparator = new Comparator<ItemLocation>() {
    @Override
    public int compare(ItemLocation o1, ItemLocation o2) {
        return Integer.valueOf(o1.id).compareTo(o2.id);
    }
}

public void sort(final String field, List<ItemLocation> itemLocationList) {

    final Comparator<ItemLocation> comparator;

    if(field.equals("title")) {
        comparator = titleComparator;
    } else if (field.equals("id")) {
        comparator = idComparator;
    } else {
        throw new IllegalArgumentException("Comparator not found for " + field);
    }

    Collections.sort(itemLocationList, comparator);
}
于 2012-08-02T11:11:24.267 に答える
0

動作していない発信コードを投稿できますか?あなたが提供したコードに明らかに問題があることはわかりません。

まず、次のような追加のelseケースを入れてみてください。

else {
    throw new IllegalArgumentException("Unrecognised field name");
}

現時点では、呼び出し元のコードにタイプミスがあると、コンパレータは常に0を返し、リストはソートされないままになります。

フィールドを渡すためのより堅牢な方法は、列挙型を宣言することです。

enum ItemLocationField {
    TITLE,
    ID
}

次に、条件は次のようになります。

if (field == ItemLocationField.TITLE)

等々。これにより、タイプミスが発生する可能性が低くなります(コンパイラーがタイプミスを行うかどうかを通知します)。

于 2012-08-02T11:13:42.233 に答える
0

1. 1つの属性のみに基づいてオブジェクトを並べ替える場合は、[java.lang.Comparableインターフェイス]に移動します。Collections.sort(List<T> list)

2.複数の属性に基づいてオブジェクトを並べ替える場合は、[java.util.Comparatorインターフェイス]に移動し ます。Collections.sort(List<T> list, Comparator<? super T> c)

于 2012-08-02T12:11:56.827 に答える
0

returning 0パラメータを と比較する以外に、何も問題はありませんequals。パラメータの大文字とthrowing RuntimeException小文字を無視することをお勧めします。returning 0equalsIgnoreCaseequals

public static void sort(final String field, List<ItemLocation> itemLocationList) {
    Collections.sort(itemLocationList, new Comparator<ItemLocation>() {
        @Override
        public int compare(ItemLocation o1, ItemLocation o2) {
            if(field.equalsIgnoreCase("title")) {
                return o1.title.compareTo(o2.title);
            } else if(field.equalsIgnoreCase("id")) {
                return Integer.valueOf(o1.id).compareTo(o2.id);
            }else
                throw new IllegalArgumentException("Invalid Parameter .");
        }
    });
}
于 2012-08-02T11:20:33.340 に答える