Java: реализовать Compararable, но слишком много условных операторов if.Как я могу избежать их? - PullRequest
0 голосов
/ 22 января 2012

У меня есть list объектов, которые реализуют Comparable.

Я хочу отсортировать этот список, и поэтому я использовал Comparable.

Каждый объект имеет поле, weight, которое состоит из 3 других переменных типа int.

compareTo возвращает 1 для объекта с наибольшим количеством weight.
Наибольшее значение имеет вес не только, если

weightObj1.member1 > weightObj2.member1  
weightObj1.member2 > weightObj2.member2  
weightObj1.member3 > weightObj2.member3

, но на самом деле немного большесложный, и я в конечном итоге с кодом слишком много условных if.

Если weightObj1.member1 > weightObj2.member1 имеет значение, то меня волнует weightObj1.member2 > weightObj2.member2.

и наоборот.

В противном случае, если weightObj1.member2 > weightObj2.member2 выполнено, я забочусь о weightObj1.member3 > weightObj2.member3 и наоборот.

Наконец, если выполняется weightObj1.member3 > weightObj2.member3 И если определенное условие выполнено, тогда это weightObj1 выигрывает и наоборот

Мне было интересно, есть ли подход к проектированию для чего-то подобного?

Ответы [ 5 ]

6 голосов
/ 22 января 2012

Вы можете попробовать с CompareToBuilder от Apache commons-lang:

public int compareTo(Object o) {
   MyClass myClass = (MyClass) o;
   return new CompareToBuilder()
     .appendSuper(super.compareTo(o)
     .append(this.field1, myClass.field1)
     .append(this.field2, myClass.field2)
     .append(this.field3, myClass.field3)
     .toComparison();
}

См. Также

3 голосов
/ 22 января 2012

Аналогично вышеупомянутому Apache CompareToBuilder, но с поддержкой обобщений, Guava предоставляет ComparisonChain:

public int compareTo(Foo that) {
  return ComparisonChain.start()
     .compare(this.aString, that.aString)
     .compare(this.anInt, that.anInt)
     .compare(this.anEnum, that.anEnum, Ordering.natural().nullsLast())
          // you can specify comparators
     .result();
}
1 голос
/ 22 января 2012

API для Comparable сообщает:

Настоятельно рекомендуется (хотя и не обязательно), чтобы естественный заказы должны соответствовать с равными.

Поскольку интересующие значения являются int значениями, у вас должно получиться единственное значение, которое фиксирует все сравнения и другие преобразования, необходимые для сравнения двух объектов. Просто обновите одно значение при изменении любого из значений элемента.

0 голосов
/ 22 января 2012

Вы можете попробовать что-то вроде этого:

int c1 = o1.m1 - o2.m1;
if (c1 != 0) {
    return c1;
}

int c2 = o1.m2 - o2.m2;
if (c2 != 0) {
    return c2;
}

return o1.m3 - o2.m3;

, поскольку сопоставимое не должно просто возвращать -1, 0 или 1. Оно может возвращать любое целочисленное значение, и рассматривается только знак.

0 голосов
/ 22 января 2012

Вы можете попробовать использовать отражение, перебрать свойства и сравнить их.

...