3

ルールで並べ替える必要のあるオブジェクトの範囲があります。ただし、ルールを切り替える必要がありますが、順序付けルールのセットは限られています。そのための最良の選択はどのデータ構造ですか?

例として、私はこのクラスを持っています:

class Test {
    public final int amount;
    public final int cost;
    public final String name;
    public final int whatever;
    // ...

    // TODO: add a constructor to set the fields :-)
}

これらのフィールドを保存して、金額、コスト、名前などで並べ替えるにはどうすればよいですか。しかし、そのルールの1つにすぎません。

カスタムでsort関数を呼び出すArrayListorまたはaを使用することを想像できます。しかし、これが効率だとは想像できません。これはモバイルデバイスでは重要だと思います。それを達成するためのより良い方法は何ですか?HashSetComparator

4

5 に答える 5

5

Set順序がないため、並べ替えには使用できません。List持つことと習慣のすべての概念がいかにComparator<T>合理的であるか。

そのソリューションを使用する必要があり、この時点ではパフォーマンスを気にする必要はありません。得られた結果に満足できない場合は、より良い解決策を考え出すようにしてください。

最善の解決策は、ストレージから適切な順序でデータを読み取ることです。あなたのアプリがその構造をどのように保存しているかわかりません。したがって、私はそれであなたを助けることはできません。しかし、同等のソリューションを実装すると、それほど悪くないことがわかります。

モバイルデバイスで重要なのはメモリ使用量です。アプリケーションでこれらの並べ替え操作の多くを使用する場合は、コンパレータを列挙型として作成して、1回だけ読み込まれるようにし、さらにコードを簡略化することができます。

private enum  TestComparator implements Comparator<Test> {
 BY_NAME {

    @Override
    public int compare(Test o1, Test o2) {

       //We validate first against null

       return o1n.name.compareTo(o2.name);

    }               
  }
 BY_WHATEVER{

    @Override
    public int compare(Test o1, Test o2) {

       //We validate first against null
      return (o1.whatever<o2.whatever ? -1 : (o1.whatever==o2.whatever ? 0 : 1));
    }               
  }

}
于 2012-11-21T07:46:30.137 に答える
3

これを行う:

class Test {
public final int amount;
public final int cost;
public final String name;
public final int whatever;
// ...

// TODO: add a constructor to set the fields :-)

    class TestAmountComparator implements Comparator<Test> {
        @Override
        public int compare(Test t1, Test t2) {
            return Integer.valueOf(t1.amount).compareTo(Integer.valueOf(t2.amount))          
        }
    }

    class TestCostComparator implements Comparator<Test> {
        @Override
        public int compare(Test t1, Test t2) {
            return Integer.valueOf(t1.cost).compareTo(Integer.valueOf(t2.cost))          
        }
    }

}

テストオブジェクトをArrayList(または他のコレクション)に保存してから、次のように並べ替えます。

List<Test> list = new ArrayList<Test>(myTest); //your Test list
//sorting
Collections.sort(list, new TestAmountComparator()); //sort by amount
Collections.sort(list, new TestCostComparator()); //sort by cost
于 2012-11-21T07:56:15.740 に答える
1

Comparableインターフェースを実装し、クラスにcompareToメソッドを実装することをお勧めします。これは、異なるデータ構造間でソートする一貫性のある動作を提供します。この場合、コンパレータインターフェイスは、特別な並べ替えが必要な場合にのみ使用されます。

class Test implements Comparable {
    public final int amount;
    public final int cost;
    public final String name;
    public final int whatever;
    // ...
    //add equals ,hashcode, and compareTo method in the class...
    // TODO: add a constructor to set the fields :-)
}

インスタンスが一意であり、比較可能なものが実装されている場合は、TreeSetを使用できます。それ以外の場合は、リストを使用して、Collection.sort関数を使用して並べ替える必要があります。

アクセスの使用に基づいてDSを決定できます。要素に順番にアクセスする場合は、LinkedList elseuserArrayListを使用します

于 2012-11-21T08:02:11.647 に答える
1

私のバージョン:

class Test3 implements Comparable<Test3> {
    public int amount;
    //...

    Comparator<Test3> comparator;

    public void setComparator(Comparator<Test3> comparator) {
        this.comparator = comparator;
    }

    @Override
    public int compareTo(Test3 o) {
        return comparator.compare(this, o);
    }
}
于 2012-11-21T08:24:50.963 に答える
0

これは、重複を失うことなくTreeSetを使用する方法です。

import java.util.Comparator;
import java.util.TreeSet;

    public class Test {
        int amount;

        Test(int amount) {
            this.amount = amount;
        }

        public static void main(String args[]) throws Exception {
            Comparator<Test> c = new Comparator<Test>() {
                @Override
                public int compare(Test o1, Test o2) {
                    if (o1.amount >= o2.amount) {
                        return 1;
                    }
                    return -1;
                }
            };
            TreeSet<Test> s = new TreeSet<Test>(c);
            s.add(new Test(2));
            s.add(new Test(1));
            s.add(new Test(1));
            for (Test t : s) {
                System.out.println(t.amount);
            }

        }
    }

これは印刷します:

1
1
2
于 2012-11-21T09:24:15.640 に答える