比较Double类型的对象时出错?

use*_*667 2 java double

这个问题出现在这段代码之后(二进制搜索的实现).如果有人能告诉我为什么没有输出预期答案,我将不胜感激:

public static void main(String[] args){
    Double[] array = {0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0};
    BinarySearch s = new BinarySearch(array);
    System.out.println(s.searchNextHighest(2.0));
}

public BinarySearch(Double[] array){
    numbers = array;
}

public Integer searchNextHighest(Double y){
    return binarySearchNextHighest(0, numbers.length-1, y, numbers);
}

public Integer binarySearchNextHighest(int min, int max, Double target, Double[] array){
    int mid = (min+max)/2;

    if(target==array[mid]){ //Fails here
        return mid;
    }

    if(max<min){
        if(min>=array.length) return null;
        return mid;
    }

    if(target>array[mid]){
        return binarySearchNextHighest(mid+1, max, target, array);
    }else{
        return binarySearchNextHighest(min, mid-1, target, array);
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:1

我跟着一个调试器并且绝对肯定.在某个时刻,target = 2.0,mid = 2,array [mid] = 2.0.然而,if语句没有执行.

奇怪的是,使用整数数组/目标时不会发生此错误.

这里发生了什么?我认为这些事情只发生在比较非常大的数字时.还有哪些陷阱?

[编辑]这是一个简化版本:

public static void main(String[] args){
    Double[] array = {2.0};
    Double target = 2.0;
    if(array[0] == target) System.out.println("Yay!");
}
Run Code Online (Sandbox Code Playgroud)

输出:无

[EDIT2]

public static void main(String[] args){
    double[] array = {3.0};
    double target = 3.0;
    if(array[0] == target) System.out.println("Yay!");
}
Run Code Online (Sandbox Code Playgroud)

输出:耶!

评论中有人指出这个错误是比较对象的结果.为什么不自动打开包装?

[EDIT3]这是使用Integer对象的代码:

public static void main(String[] args){
    Integer[] array = {3};
    Integer target = 3;
    if(array[0] == target) System.out.println("Yay!");
}
Run Code Online (Sandbox Code Playgroud)

输出:耶!

所以我猜原因很明显,但为什么Integer对象的实现方式却如此不同?这会自动解压缩.

sas*_*llo 6

double并且Double是两件不同的事情.Double创建一个对象,如果它们指向内存中的相同地址,它们将是相等的.它们所持有的值可以相同,但它们是不同的对象,因此不相等.与...相同Integer.对于您的代码,您可以使用double或比较通过.doubleValue().equals()方法Double来比较值.

编辑:正如@MarkPeters和@TedHopp在评论中指出的那样,Integer行为有点不同,这里有更多信息.

  • @ user2316667:这是JVM的细微差别.允许从-128到127(最小;允许更大范围)的整数缓存,这样如果你将该范围内的`int`自动放入一个`Integer`,它将使用一个共享实例.参见[Integer.valueOf()`]的文档(http://docs.oracle.com/javase/7/docs/api/java/lang/Integer.html#valueOf(int)).试一试大数字,比如说"1000000". (3认同)