简体   繁体   English

使用Math.sqrt()作为参数时,列表包含方法返回false

[英]List contains method returns false when using Math.sqrt() as a parameter

I am refreshing my knowledge in Java and working on an exercise from codewars. 我正在刷新我的Java知识,并从事代码战的练习。 The problem is to compare two arrays if the elements are the "same". 问题是如果元素“相同”,则比较两个数组。 The meaning of "same" is that the elements in 'b' are the elements in 'a' squared, regardless of the order. “相同”的含义是,“ b”中的元素是“ a”中平方的元素,而与顺序无关。 The solution that I was trying to do is to get the square root of element in 'b' and check if it does exists in element 'a' using Math.sqrt(). 我尝试执行的解决方案是使用Math.sqrt()获取元素“ b”的平方根,并检查元素“ a”中是否存在该元素。 However, when I use that as a parameter for contains(), it always returns false. 但是,当我将其用作contains()的参数时,它总是返回false。

So to check if the square root of element 'b' really does exists in 'a', I tried a simple if-else to check a specific element. 因此,要检查元素“ b”的平方根是否确实存在于“ a”中,我尝试了一个简单的if-else检查特定元素。 But when I incorporate it with Math.sqrt(), that's where the problem rise. 但是,当我将其与Math.sqrt()合并时,就会出现问题。

Here's the elements of set a and b 这是集合a和b的元素

int[] a = {121, 144, 19, 161, 19, 144, 19, 11};
int[] b = {121, 14641, 20736, 361, 25921, 361, 20736, 361};

That I have converted to List 我已经转换为列表

List<Integer> setAList = Arrays.stream(setA)//int[] setA - parameter of a function
                                                    .boxed()
                                                    .collect(Collectors.toList());
List<Integer> setBList = Arrays.stream(setB)//int[] setB - parameter of a function
                                                    .boxed()
                                                    .collect(Collectors.toList());

I converted the array to List to take advantage of contains() method. 我将数组转换为List,以利用contains()方法。 This is my code when I tried to check the specific element 这是我尝试检查特定元素时的代码

double sqrd = Math.sqrt(setBList.get(6));
return setAList.get(5) == sqrd ? true : false;

And that gave an expected result - true. 那给出了预期的结果-是的。 Now here's the code of when I incorporated it to a for loop 现在是我将其合并到for循环中时的代码

boolean same = true;

for(int indexB : setB) {
    same = setAList.contains(Math.sqrt(indexB)) ? true : false; 
    System.out.println(Math.sqrt(indexB) + " " + same);

}

And here's the result 这就是结果

11.0 false
121.0 false
144.0 false
19.0 false
161.0 false
19.0 false
144.0 false
19.0 false
false

At first I though the problem might be because of the data types but I have tried casting the double to int but I'm still getting the same result. 起初我虽然问题可能是由于数据类型引起的,但我尝试将double强制转换为int,但仍得到相同的结果。

Not a direct answer, but a workaround to avoid this kind of issues: 不是直接的答案,而是一种避免此类问题的解决方法:

As explained in other answers, your problem is a cast problem because you have to deal with double and int values and won't have to face casting issues. 如其他答案所述,您的问题是强制转换问题,因为您必须处理doubleint值,而不必面对强制转换问题。

A way to avoid it is to square values in A instead of calculating the square roots of values in B. This way you only ever deal with int values 避免它的方法是广场一,而不是计算值的平方根源B.这个你永远只处理方式的值int

int[] a = {121, 144, 19, 161, 19, 144, 19, 11};
int[] b = {121, 14641, 20736, 361, 25921, 361, 20736, 361};

// Make a list containing the squares out of the b array
List<Integer> squares = Arrays.stream(b)
    .boxed()
    .collect(Collectors.toList());

// square all the values in B,
// and check that all the resultant values are present in the squares list
boolean same = Arrays.stream(a) // Stream<Integer> containing values in array a
    .map(i -> i* i) // Stream<Integer> containing values in array a squared
    .allMatch(squares::contains); // reduce to a boolean insuring that all values in the Stream<Integer> are present in the squares list

System.out.println(same);

setAList.get(5) == sqrd gives you the expected result because of the widening primitive conversion of setAList.get(5) (which is an int ) to a double . setAList.get(5) == sqrd为您提供了预期的结果,因为setAList.get(5) (是int )的原始图元转换double

If you've got setAList.contains(Math.sqrt(indexB)) , you need to do the cast manually: setAList.contains((int)Math.sqrt(indexB)) . 如果您拥有setAList.contains(Math.sqrt(indexB)) ,则需要手动进行setAList.contains((int)Math.sqrt(indexB))setAList.contains((int)Math.sqrt(indexB))

Looking up exact floating point values, as is done in contains() , is a bad idea most of the time due to the limited precision of floating point values; 就像在contains()那样,查找精确的浮点值在大多数情况下是一个坏主意,因为浮点值的精度有限。 you can try yourself and see for which numbers Math.sqrt( number ) * Math.sqrt( number ) is not the same as number : 你可以尝试自己,看看哪些号码Math.sqrt( number ) * Math.sqrt( number )一样的number

for (int i = 0; i < 100; i++) {
  final double r = Math.sqrt(i);
  final double s = r * r;
  if (s != i) {
    System.out.println(i + " != " + s);
  }
}

(Prints out 51 non-equal roots-squared out of the 100 numbers tested.) (在测试的100个数字中,打印出51个不相等的平方根。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM