我有一些具有id和值的项目,我正在寻找最大元素。
值是浮点数/双打数,并且打破平局时我想使用ID较小的对象。
一种方法如下:
double maxValue = Double.NEGATIVE_INFINITY;
Item maxItem = null;
for (Item item : items) {
if (item.value() > maxValue) {
maxValue = item.value();
maxItem = item;
} else if (item.value() == maxValue && item.id() < maxItem.id()) {
maxItem = item;
}
}
然而,这包括使用浮点数进行质量比较,这是不鼓励的,在我的情况下也会在代码分析步骤中产生一个关键问题。
当然,我可以写一些东西来避免这个问题,例如使用>=
进行第二次比较,但从可读性的角度来看,我未来或任何其他读者可能会怀疑它是否是一个错误。
我的问题:是否有一种方法可以很好地表达意图并避免使用==
进行浮动比较来完成此任务?
答案 0 :(得分:0)
在这种情况下,测试两个浮点值的相等性没有任何问题。两个float / double值可以相等,可以使用==
运算符进行测试。
不建议对浮点值使用==
的一个原因是,将它们与文字常量进行比较会导致意外行为,因为文字通常以十进制表示法编写,而浮点变量则以二进制表示。并非所有十进制值都可以用二进制精确表示,因此变量的值只是十进制值的近似值。例如:3.0 * 0.1 == 0.3
的计算结果为false。
另一个原因是浮点值并不总是像实数一样。特别是,浮点运算不一定是可交换的(x * y == y * x
)和关联的((x * y) * z == x * (y * z)
)。例如,(0.3 * 0.2) * 0.1 == 0.3 * (0.2 * 0.1)
的计算结果为false。
但是,在您的情况下,没有理由不使用==
。
答案 1 :(得分:0)
你可以写一个Comparator<Item>
,然后用它来找到最好的项目:
Comparator<Item> byValueAscThenIdDesc = (i1, i2) -> {
int valueComparison = Double.compare(i1.value(), i2.value());
if(valueComparison == 0) {
int idComprison = Integer.compare(i1.id(), i2.id());
return -idComparison;
}
return valueComparison;
};
List<Item> items = new ArrayList<>();
Item max = items.stream().max(byValueAscThenIdDesc).get();