user2316667
user2316667

Reputation: 5634

Error When Comparing Objects of Type Double?

This question comes after this piece of code (an implementation of binary search). I would appreciate if someone could tell me why this is not outputting the expected answer:

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);
    }
}

Output: 1

I followed through a debugger and made absolute sure. At a certain moment, target = 2.0, and mid=2, and array[mid] = 2.0. Yet the if statement does not execute.

Curiously, this error does not occur when Integer arrays/targets are used.

What is happening here? I thougt these things only happened when comparing very big numbers. What other pitfalls exist?

[EDIT] Here is a simplified version:

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

Output: None

[EDIT2]

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

Output: Yay!

Someone in comments pointed out that this error was a result of comparing objects. Why isn't it automatically unpacking?

[EDIT3] Here is code using the Integer object:

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

Output: Yay!

So I guess the reason is obvious, but why is the object Integer implemented so differently? That is automatically unpacks itself.

Upvotes: 2

Views: 148

Answers (2)

Prabhaker A
Prabhaker A

Reputation: 8473

use the equals() method to compare content of two objects.

 if(target.equals(array[mid])){
    return mid;
}  

According to Double#equals

Compares this object against the specified object. The result is true if and only if the argument is not null and is a Double object that represents a double that has the same value as the double represented by this object.

Please also look into What's the difference between ".equals" and "=="?

Upvotes: 3

sashkello
sashkello

Reputation: 17871

double and Double are two different things. Double creates an object and they will be equal if they are pointing to the same address in memory. The values they are holding can be the same, but they are different objects, so not equal. Same with Integer. For your code you can use double instead or compare through .doubleValue() or .equals() method for Double to compare the values.

EDIT: As pointed out by @MarkPeters and @TedHopp in comments, Integer behaves a bit differently, more info here.

Upvotes: 6

Related Questions