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.
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With