只是将我的问题放在上下文中:我有一个类,它根据每个元素的计算得分对其构造函数中的列表进行排序。现在我想将我的代码扩展到不对列表进行排序的类的版本。最简单的(但显然不干净,我完全清楚,但时间紧迫,我现在没有时间重构我的代码)解决方案就是使用分数计算器,为每个元素分配相同的分数。
我应该选择哪个双倍价值?我个人认为+ Infinity或-Infinity因为我认为它们具有特殊的表示,这意味着它们可以快速比较。这是正确的假设吗?我不太了解java的低级实现,以确定我是否正确。
答案 0 :(得分:1)
不确定这会怎样,但你考虑过自己编写吗?
关于您正在寻找具有特定性能特征的对象,这似乎有点令人担忧,这些特性不太可能始终出现在一般实现中。即使你通过实验或甚至从源代码找到一个完美的候选人,你也无法保证合同。
static class ConstDouble extends Number implements Comparable<Number> {
private final Double d;
private final int intValue;
private final long longValue;
private final float floatValue;
public ConstDouble(Double d) {
this.d = d;
this.intValue = d.intValue();
this.longValue = d.longValue();
this.floatValue = d.floatValue();
}
public ConstDouble(long i) {
this((double) i);
}
// Implement Number
@Override
public int intValue() {
return intValue;
}
@Override
public long longValue() {
return longValue;
}
@Override
public float floatValue() {
return floatValue;
}
@Override
public double doubleValue() {
return d;
}
// Implement Comparable<Number> fast.
@Override
public int compareTo(Number o) {
// Core requirement - comparing with myself will always be fastest.
if (o == this) {
return 0;
}
return Double.compare(d, o.doubleValue());
}
}
// Special constant to use appropriately.
public static final ConstDouble ZERO = new ConstDouble(0);
public void test() {
// Will use ordinary compare.
int d1 = new ConstDouble(0).compareTo(new Double(0));
// Will use fast compare.
int d2 = ZERO.compareTo(new Double(0));
// Guaranteed to return 0 in the shortest time.
int d3 = ZERO.compareTo(ZERO);
}
显然,您需要在收藏中使用Comparable<Number>
而不是Double
,但这可能并不是件坏事。您可以设计一种机制来确保始终优先使用快速跟踪比较(取决于您的使用情况)。
答案 1 :(得分:1)
通常会避免0.0
,-0.0
和NaN
。任何其他数字都没问题。您可以查看Double.compare
实现,看看它们是否经过特殊处理:
if (d1 < d2)
return -1; // Neither val is NaN, thisVal is smaller
if (d1 > d2)
return 1; // Neither val is NaN, thisVal is larger
// Cannot use doubleToRawLongBits because of possibility of NaNs.
long thisBits = Double.doubleToLongBits(d1);
long anotherBits = Double.doubleToLongBits(d2);
return (thisBits == anotherBits ? 0 : // Values are equal
(thisBits < anotherBits ? -1 : // (-0.0, 0.0) or (!NaN, NaN)
1)); // (0.0, -0.0) or (NaN, !NaN)
然而,这取决于您的排序比较器的实现方式。如果你不使用Double.compare
,那么可能没关系。
请注意,除了这些具有0.0/-0.0/NaN
双重数字比较的特殊情况之外,它在CPU内部连接并且非常快,因此与您已有的其他代码相比,您不太可能获得任何显着的比较开销。