目前我正在以下列形式编写二次函数的compareTo方法:ax ^ 2 + bx + c。
a,b,c是通过构造函数传递给类的整数系数。
在compareTo方法中,我应该首先比较两个函数之间的a系数,但如果它们相等,我会比较b系数。如果b是相等的,我比较c。
我为此提出的方法最终变得相当丑陋:
public int compareTo(QuadraticFunction other)
{
if (a > other.a)
return 1;
else if (a < other.a)
return -1;
else if (b > other.b)
return 1;
else if (b < other.b)
return -1;
else if (c > other.c)
return 1;
else if (c < other.c)
return -1;
else
return 0;
}
所以我想知道,如果你有这些“分层”的比较系统(比如在c之前比较a之前的b),那么实现它们的最佳方法是什么?如果你不得不经历10多个变量,我无法想象像我一样编写一种方法。
答案 0 :(得分:6)
对于任意数量的系数(所有相同类型),您应该将它们存储在List
(或类似的东西)中,而不是单独命名的成员变量。这允许您将示例代码转换为迭代。
答案 1 :(得分:2)
Guava Libraries提供了一个非常好的工具,名为ComparisonChain。
您的代码看起来像这样:
import com.google.common.base.ComparisonChain;
...
public int compareTo(QuadraticFunction other) {
return ComparisonChain.start()
.compare(a, other.a)
.compare(b, other.b)
.compare(c, other.c)
.result();
}
答案 2 :(得分:1)
为了便于阅读,并使用a,b,c的内置比较方法,我会重构:
public int compareTo(QuadraticFunction other) {
if (a.equals(other.a)) {
if (b.equals(other.b))
return c.compareTo(other.c);
return b.comapreTo(other.b);
}
return a.compareTo(other.a);
}
此代码假定字段为Number
。如果它们是基元,则将它们转换为包裹类型或更改a.equals(b) to
a == b and change
a.compareTo(b)to
a - b`。
另请注意,当if
返回时,永远不需要else
- 这是多余的,因此请将其删除。
答案 3 :(得分:0)
您可以使用如下所示的成语,将比较分为按字段清除的部分,每个字段只需要一次测试,并使用signum
方法生成返回值。
注意,下面的减法适用于int
,short
,char
或byte
字段。
对于long
,float
和double
字段,您必须对<
和==
使用单独的检查,以避免溢出/下溢,并且由于四舍五入。比较浮点值时要小心NaN
。
对于Comparable
字段,您可以在使用单独的条件处理compareTo
之后将delta设置为null
的结果。
long delta = ((long) a.field1) - b.field1;
if (delta != 0) { return Long.signum(delta); }
delta = ((long) a.field2) - b.field2;
if (delta != 0) { return Long.signum(delta); }
...
return 0;