当前位置: 首页 > 知识库问答 >
问题:

怎样才能摆脱不及物比较器?

暨弘毅
2023-03-14

我有一个比较器

float d = o1.bar - o2.bar;
if (Math.abs(d) <= 0.001) {
    return 0;
} else {
    return d < 0 ? -1 : 1; // inline Math.copySign
}

本质上,这应该是根据bar属性比较两个Foos,除非值足够接近,在这种情况下,它们应该被声明为相等。(这很重要,因为我在另一处房产上做了另一种分类。)

不过,很明显,这不是一个传递比较器。如果有Foosf1f2f3bar的值分别为1.9992.0002.001,那么根据我的比较器,f1==f2f2==f3f1!=f3

调用的排序(myListofFoo, myFo的比较)给出了一个比较方法违反了它的一般合同!错误很少,但确定。

如何在不生成此错误的情况下将这样的比较器与 Collections.sort(List, Comparator) 一起使用?

或者,有没有什么方法可以存储我的数据,让比较器正常工作?在构造时将每个浮点路由到最近的0.001将是最简单的解决方案,除了Foo.bar字段实际上是基于任意距离度量计算的,所以没那么简单。

实际代码是:

float d = metric.distance(vertex, o1)
        - metric.distance(vertex, o2);
if (Math.abs(d) < threshold) {
    return 0;
} else {
    return d < 0 ? -1 : 1; // inline Math.copySign
}

其中o1o2顶点类Point{浮点x;浮点y;}度量接口距离度量{浮点距离(Point p1, Point p2);}的实例。值得注意的是,即使在标准欧几里得度量上,这也失败了。


共有2个答案

微生俊名
2023-03-14

我猜你实际上想做的是删除重复值(根据你的阈值),然后对其余的进行排序。你为什么不首先根据非四舍五入的值进行自然排序,然后根据你的阈值使用过滤。

左丘成天
2023-03-14
匿名用户

恐怕Java7排序实现不会容忍表现出不敏感的Comparator。如果您想使用标准的JavaSE排序API,您对此无能为力。

但是,事实上,在排序中使用阈值比较实际上在数学上是不正确的。

比较浮点值时的问题是,它们通常一开始就不精确,然后计算通常会在结果中引入更小的误差。当两个结果足够接近时,累积误差可能大于两个值之间的差值...这意味着我们无法判断理想数字(没有误差)是小于、等于还是大于每个误差。我们通过使用阈值进行比较,将“接近相等”视为“相等”来处理这个问题。

当我们对值进行排序(即按顺序排列)时,需要以不同的方式处理值中的错误问题。假设

> < li>

我们有两个号码< code>v1 e1和< code>v2 e2,以及

当我们使用阈值比较比较数字时,阈值大于mod(e1)mod(e2)

如果事实证明 v1 和 v2 足够接近 mod(v1 - v2)

因此,如果我们忽略错误并简单地使用精确比较对数字进行排序,那么当我们使用基于阈值的比较时,我们不会以不正确的顺序排列任何一对数字。

现在假设我们有v1±e1v2±e2v3±e3…并且mod(e1)mod(e3)是我们的阈值大:

>

  • 如果我们按照上面的顺序排序(使用精确的比较),我们仍然会以正确的顺序得到数字。

    如果我们使用“与阈值比较”来对值进行排序(排序实现允许这样做!),我们最终可能会得到 v3 ± e3v2 ± e2 和 v1 ± e1 的数字。我们有 {v1 ± e1、v2 ± e2} 和 {v2 ± e2、v3 ± e3} 成对相等,但我们也可能有 {v1 ± e3、v3 ± e3} 错误排序,即使我们使用基于阈值的比较进行比较!

    底线是您应该简单地实现您的< code >比较器(用于排序目的!)来使用精确比较。阈值比较不适用于此上下文。这与< code>sort算法的编码方式无关...

  •  类似资料:
    • 我有JavaWebService代码在我的eclipse。我使用了@WebService@Webmethod,@XmlElements,@XmlType,@XmlAccessorType 现在我正在使用cxf框架中的java2ws命令生成wsdl。这是命令 我的wsdl文件包含agr0作为我不想要的名称,因为当我将其导入SoapUI时。它正在字段周围添加标记。 下面是带有arg0的wsdl部分 下

    • 问题内容: 我正在使用Apache Derby嵌入式数据库在Maven项目中进行单元测试。不幸的是,每当运行测试时,我最终都会在项目根目录中找到该文件。数据库本身是在目录()中创建的,因此这不是问题。在查阅参考指南之后, 我尝试在JDBC url()上设置参数,但这似乎是针对其他日志的,因此仍然会出现。 任何帮助深表感谢。 问题答案: 您可以通过创建以下类来摆脱文件 并设置JVM系统属性,例如,使

    • 在这段代码中,我从\u RETURN\u VALUE得到了\u SOME\u PATH\u上的

    • 我使用Quarkus 1.10.3.final(包括quarkus-resteasy-jackson和quarkus-smallrye-openapi)和Immutables库(org.immmutables:value:2.8.8)来定义各种应用程序模型。我的问题是,大摇大摆的UI似乎不能识别标准的jackson@jsonSerialize(as=)和@jsonDeserialize(as=)注

    • 有什么方法可以简化这段代码吗?我正好有一个白色的一块,想要得到它的位置 代码: 瓦片类: 件类:

    • 问题内容: 到目前为止,给我带来了很多麻烦,所以我想摆脱它。尽管spring框架文档清楚地说明了应该做的事情,但实际上 并没有摘要列表。 所以我一直坚持删除并得到错误 -在名称为的中找不到带有请求的映射 对于所有应该由控制器类解决的Url(在这种情况下:)。有什么建议可以让我了解更多信息吗?我非常想知道到底由代表什么标签。 问题答案: 你可以用来自定义定义的每个bean 。现在,javadocs详