Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 稳健地图<;双倍;在爪哇_Java_Collections - Fatal编程技术网

Java 稳健地图<;双倍;在爪哇

Java 稳健地图<;双倍;在爪哇,java,collections,Java,Collections,我正在寻找Java中的健壮映射,其中键查找将考虑Double具有有限的精度(大约1e-15或1e-16)。我在哪里能找到这样的东西 编辑:按照Jon的建议,我认为定义等价性是有意义的。一个想法是将这些数字集中在四舍五入到15个最相关的十进制数字。其他数字将四舍五入(以任何一致的方式-最快实现)。这有意义吗?最好的实现方式是什么 我建议您使用TreeMap并实现您自己的自定义比较器,该比较器在考虑到所需精度的情况下比较两个双精度值。我不完全确定您需要它做什么,但您可以实现一个围绕双精度的包装器,并

我正在寻找Java中的健壮映射,其中键查找将考虑Double具有有限的精度(大约1e-15或1e-16)。我在哪里能找到这样的东西


编辑:按照Jon的建议,我认为定义等价性是有意义的。一个想法是将这些数字集中在四舍五入到15个最相关的十进制数字。其他数字将四舍五入(以任何一致的方式-最快实现)。这有意义吗?最好的实现方式是什么

我建议您使用TreeMap并实现您自己的自定义比较器,该比较器在考虑到所需精度的情况下比较两个双精度值。

我不完全确定您需要它做什么,但您可以实现一个围绕双精度的包装器,并覆盖其
hashCode()
equals()
方法以满足您的需要“有限精度”查找。因此,任何映射实现都是健壮的,因为它依赖于
hashCode()
equals()
进行键查找


当然,您的地图将采用
map

格式,最好的方法是在添加或查找值之前对值进行标准化。例如,使用舍入


顺便说一句:您可以使用支持自定义哈希策略并使用原语双键的TDoubleObjectHashMap。

总结上面的答案和评论,我最终得到了以下包装器(可能不处理NaN atm):

公共静态类DoubleWrapper{
专用静态最终整数精度=15;
私人最终双舍入值;
公共DoubleWrapper(双值){
最终双d=Math.ceil(Math.log10(值<0?-value:value));
最终整数幂=精度-(整数)d;
最终双倍震级=数学功率(10,功率);
最终长位移=数学四舍五入(值*量级);
舍入值=移位/幅度;
}
公共双精度getDouble(){
返回舍入值;
}
@凌驾
公共布尔等于(对象obj){
返回roundedValue.equals(obj);
}
@凌驾
公共int hashCode(){
返回roundedValue.hashCode();
}
}

double键?真的吗?你的需求需要更精确。特别是,如果你在寻找类似“近似等价”的东西“这最终很棘手,因为地图假定如果A和B相等,B和C相等,那么A和C也必须相等。”。这对近似等价不起作用。通过“鲁棒性”,我想你希望将1e-15范围内的两个键或每一个左右的键视为同一个键?@Jon:我认为这叫做传递性(等价关系)。存储在排序列表中并使用二进制搜索如何?我如何知道我的哪个双键是“接近”的如果不将其与映射中已存在的每个双精度进行比较,则hashCode()函数应为所有“接近”的双精度返回相同的哈希代码。对于那些“接近”的双打,equals()也应该为true。无需比较地图中的所有双精度。毫无疑问,这是可以的,但由于Jon Skeet和Mitch Wheat在评论中指出的及物性属性,这并不像看上去那么容易。别忘了迎合
NaN
!“闭合”-可以通过将双域拆分为多个存储单元(例如,[1.1,1.2)=1.1、[1.2,1.3)=1.2等,当然,精度需要)。
public static class DoubleWrapper {
    private static final int PRECISION = 15;
    private final Double roundedValue;

    public DoubleWrapper(double value) {
        final double d = Math.ceil(Math.log10(value < 0 ? -value: value));
        final int power = PRECISION - (int) d;

        final double magnitude = Math.pow(10, power);
        final long shifted = Math.round(value*magnitude);
        roundedValue = shifted/magnitude;

    }

    public double getDouble() {
        return roundedValue;
    }

    @Override
    public boolean equals(Object obj) {
        return roundedValue.equals(obj);
    }

    @Override
    public int hashCode() {
        return roundedValue.hashCode();
    }
}