13

同等のものを実装できないクラスがありますが、2つのフィールドに基づいてソートする必要があります。どうすればGuavaでこれを達成できますか?

クラスが次のようになっているとしましょう。

class X {
  String stringValue;
  java.util.Date dateValue;
} 

そして、私はこれらのリストを持っています:

List<X> lotsOfX;

最初に値フィールドに基づいて並べ替え、次に「値」フィールドの各「グループ」内で降順のdateValueに基づいて並べ替えます。

私がこれまでやってきたことは:

List<X> sortedList = ImmutableList.copyOf(Ordering.natural().onResultOf(dateValueSortFunction).reverse().sortedCopy(lotsOfX));
sortedList = ImmutableList.copyOf(Ordering.natural().onResultOf(stringValueSortFunction).sortedCopy(sortedList));

関数は次のように定義されます。

public class DateValueSortFunction<X> implements Function<X, Long> {

    @Override
      public Long apply(X input) {
        return input.getDateValue().getTime();  //returns millis time
      }
}

と:

public class StringValueSortFunction<X> implements Function<X, Integer> {

      @Override
        public Integer apply(X input) {
          if(input.getStringValue().equalsIgnoreCase("Something"))
            return 0;
          else if(input.getStringValue().equalsIgnoreCase("Something else"))
            return 1;
          else
            return 2;
        }
}

で期待される出力sortedListは次のとおりです。

Something   03/18/2013
Something   03/17/2013
Something else  03/20/2013
Something else  03/19/2013
....

私のアプローチは機能しますが、リストを2回トラバースするには明らかに非効率的です。これを行うためのより良い方法はありますか?

これをGWTアプリで使用しています。同等のものを実装することはオプションではありません。

4

3 に答える 3

24

私はあなたがしたいと思いOrdering.compoundます。1 つのステートメントですべてを実行できますが、次のステートメントを使用します。

Ordering<X> primary = Ordering.natural().onResultOf(stringValueSortFunction);
Ordering<X> secondary = Ordering.natural()
                              .onResultOf(dateValueSortFunction)
                              .reverse();
Ordering<X> compound = primary.compound(secondary);

List<X> sortedList = compound.immutableSortedCopy(lotsOfX);
于 2013-03-20T19:31:48.200 に答える
17

機能は劣りますが、間違いなくクリーンなソリューション:

new Ordering<X>() {
  public int compare(X x1, X x2) {
    return ComparisonChain.start()
      .compare(x1.stringValue, x2.stringValue)
      .compare(x2.dateValue, x1.dateValue) // flipped for reverse order
      .result();
  }
}.immutableSortedCopy(listOfXs);
于 2013-03-20T19:54:10.177 に答える
2

Java 8 は、チェーンされたコンパレーターを簡潔に指定する Comparator のメソッドを提供します。新しく導入された List.sort とともに、次のことができます。

lotsOfX.sort(
    Comparator.comparingInt(x -> stringValueSortFunction.apply(x.stringValue))
        .thenComparing(x -> x.dateValue, Comparator.reverseOrder()));

もちろん、これはリストを変更します。元のリストを変更しない場合は最初にコピーを作成するimmutableSortedCopyか、不変のコピーが必要な場合はコンパレータを Ordering でラップして使用します。

于 2014-10-04T23:59:51.737 に答える