使用番石榴订购对象列表的多标准排序

use*_*110 11 java sorting gwt guava

我有一个类不能实现可比性,但需要根据2个字段进行排序.我怎样才能用番石榴来实现这个目标?

让我们说这堂课是:

class X {
  String stringValue;
  java.util.Date dateValue;
} 
Run Code Online (Sandbox Code Playgroud)

我列出了这些:

List<X> lotsOfX;
Run Code Online (Sandbox Code Playgroud)

我想先根据值字段对它们进行排序,然后根据每个'组'的'value'字段中的dateValue进行排序.

到目前为止我一直在做的是:

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

功能定义为:

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

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

和:

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;
        }
}
Run Code Online (Sandbox Code Playgroud)

预期产量sortedList为:

Something   03/18/2013
Something   03/17/2013
Something else  03/20/2013
Something else  03/19/2013
....
Run Code Online (Sandbox Code Playgroud)

我的方法有效,但两次遍历列表显然效率低下.有没有更好的方法呢?

我在GWT应用程序中使用它.实施可比较不是一种选择.

Jon*_*eet 21

我怀疑你想要Ordering.compound.你可以在一个声明中完成所有操作,但我会使用:

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);
Run Code Online (Sandbox Code Playgroud)


Lou*_*man 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);
Run Code Online (Sandbox Code Playgroud)

  • 对于那些认为交换参数以获得反向顺序的人来说太过微妙,你可以传入一个比较器作为第三个参数并使用`Collections.reverseOrder()`而不是读取:`.compare(x1.dateValue,x2.dateValue, reverseOrder())`(假设你正在使用静态导入. (4认同)