是否可以设置Set的精度 。载有()?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了是否可以设置Set的精度 。载有()?相关的知识,希望对你有一定的参考价值。
假设我们有Set<Double>
的实现。它包含以下值:[2.0, 5.0, 7.0]
。
在这种情况下,contains(2.0001d)
返回false
,因为double
值通过完全匹配进行比较。
是否可以为boolean contains(Object o)
方法设置一些双精度?
如果不可能,除了在顺序集合中存储值,迭代它并比较每个值之外,您可以建议哪种解决方法?
可能你可以使用Sun's answer,例如,基于anyMatch
之后的前两位数进行比较:
.
我可以看到三个选项:
- 在将数字添加到集合之前对数字进行舍入
- 写一个
Set<Double> set = Set.of(2.0, 5.0, 7.0); Double compared = 2.0001d; System.out.println( set.stream().anyMatch(aDouble -> Math.floor(aDouble * 100) / 100 == Math.floor(compared * 100) / 100 ));
包装类并重新定义equals方法 - 使用
double
和自定义比较器
请注意,最后两个选项可能会或可能不会令人满意,因为填充集合的顺序会影响保留哪些元素。例如,如果将精度设置为0.01并添加0.01然后加上0.011然后加上0.02,则集合中将包含两个元素(0.01和0.02)。如果你加0.011然后0.01然后加0.02,你将只有一个元素:0.011。我不知道这对你的用例是否有问题。
最后一个选项可能如下所示:
TreeSet
使用示例:
static Set<Double> setWithPrecision(double epsilon) {
return new TreeSet<> ((d1, d2) -> {
if (d1 <= d2 - epsilon) return -1;
if (d1 >= d2 + epsilon) return 1;
return 0;
});
}
假设你的Set<Double> set = setWithPrecision(0.01);
set.add(0d);
set.add(0.00001d);
set.add(0.01d);
set.add(0.02d);
System.out.println(set); // [0.0, 0.01, 0.02]
调用点在一个方法中,某种方式从某个地方接收到HashSet#contains
,你可以简单地继续并设置Double
的精度。虽然Double
没有提供圆形Double
对象的开箱即用的方法,但你可以很好地创建一个舍入助手,它将接受你想要达到的精度并返回舍入的数字。
例如:
Double
通过public static Double roundToPrecision(Double number, int precision) {
return BigDecimal.valueOf(number)
.setScale(precision, RoundingMode.DOWN)
.doubleValue();
}
将有效地导致这回到2.0001d
。
以上是关于是否可以设置Set的精度 。载有()?的主要内容,如果未能解决你的问题,请参考以下文章
如何在具有灵活高度的同一部分中的集合视图中加载有条件的 Web 视图和图像视图