有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

浮点比较中的java句柄大小写相等

我有一些项目有一个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;
    }
}

但是,这包括使用浮点数进行质量比较,这是不鼓励的,在我的例子中,这也会在代码分析步骤中产生一个关键问题

当然,我可以写一些东西来避免这个问题,例如使用>=进行第二次比较,但是从可读性的角度来看,我未来的我或任何其他读者可能会怀疑这是否是一个bug

我的问题是:是否有一种方法能够很好地表达意图,并避免使用==进行此任务的浮点比较


共 (2) 个答案

  1. # 1 楼答案

    在这种情况下,测试两个浮点值的相等性没有错。两个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

    但是,在您的情况下,没有理由不使用==

  2. # 2 楼答案

    您可以编写一个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();