Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Java, how do I test whether a list of `Double` contains a particular value

Background: Floating point numbers have rounding issues, so they should never be compared with "==".

Question: In Java, how do I test whether a list of Double contains a particular value. I am aware of various workarounds, but I am looking for the most elegant solution, presumably the ones that make use of Java or 3rd party library features.

import java.util.ArrayList;
import java.util.List;

public class Test {
    public static void main(String[] args) {
        // should be 1.38, but end up with 1.3800000000000001
        Double d1 = new Double(1.37 + 0.01);
        System.out.println("d1=" + d1);

        // won't be able to test the element for containment
        List<Double> list = new ArrayList<Double>();
        list.add(d1);
        System.out.println(list.contains(1.38));
    }
}

Output is:

d1=1.3800000000000001
false

Thank you.

like image 921
Skyline Avatar asked May 17 '14 00:05

Skyline


People also ask

How do you check if a list contains a value in Java?

ArrayList contains() method in Java is used for checking if the specified element exists in the given list or not. Returns: It returns true if the specified element is found in the list else it returns false.

How do you check if an ArrayList contains a value in Java?

contains() method can be used to check if a Java ArrayList contains a given item or not. This method has a single parameter i.e. the item whose presence in the ArrayList is tested. Also it returns true if the item is present in the ArrayList and false if the item is not present.

How do you check if a string contains a double?

Using the parseDouble() method Therefore, to know whether a particular string is parse-able to double or not, pass it to the parseDouble method and wrap this line with try-catch block. If an exception occurs this indicates that the given String is not pars able to double.


1 Answers

The general solution would be to write a utility method that loops through the list and checks if each element is within a certain a threshold of the target value. We can do slightly better in Java 8, though, using Stream#anyMatch():

list.stream().anyMatch(d -> (Math.abs(d/d1 - 1) < threshold))

Note that I am using the equality test suggested here.

If you're not using Java 8, I would write a simple utility method along the lines of this:

public static boolean contains(Collection<Double> collection, double key) {
    for (double d : collection) {
        if (Math.abs(d/key - 1) < threshold)
            return true;
    }
    return false;
}

Note that you might need to add a special case to both of these approaches to check if the list contains 0 (or use the abs(x - y) < eps approach). That would just consist of adding || (abs(x) < eps && abs(y) < eps) to the end of the equality conditions.

like image 101
arshajii Avatar answered Sep 30 '22 09:09

arshajii