Java 使用Math.sqrt()作为参数时,List contains方法返回false
我正在刷新我的Java知识,并正在做一个来自codewars的练习。问题是如果两个数组的元素是“相同”的,则比较两个数组。“相同”的含义是,“b”中的元素是“a”平方中的元素,而不管顺序如何。我尝试的解决方案是获取“b”中元素的平方根,并使用Math.sqrt()检查它是否存在于元素“a”中。但是,当我将其用作contains()的参数时,它总是返回false 所以为了检查元素“b”的平方根是否真的存在于“a”中,我尝试了一个简单的if-else来检查一个特定的元素。但是当我把它与Math.sqrt()结合起来时,问题就出现了 下面是集合a和集合b的元素Java 使用Math.sqrt()作为参数时,List contains方法返回false,java,arraylist,contains,math.sqrt,Java,Arraylist,Contains,Math.sqrt,我正在刷新我的Java知识,并正在做一个来自codewars的练习。问题是如果两个数组的元素是“相同”的,则比较两个数组。“相同”的含义是,“b”中的元素是“a”平方中的元素,而不管顺序如何。我尝试的解决方案是获取“b”中元素的平方根,并使用Math.sqrt()检查它是否存在于元素“a”中。但是,当我将其用作contains()的参数时,它总是返回false 所以为了检查元素“b”的平方根是否真的存在于“a”中,我尝试了一个简单的if-else来检查一个特定的元素。但是当我把它与Math.sq
int[] a = {121, 144, 19, 161, 19, 144, 19, 11};
int[] b = {121, 14641, 20736, 361, 25921, 361, 20736, 361};
我已转换为列表
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());
这就给出了一个预期的结果——真的。
下面是我将其合并到for循环时的代码
boolean same = true;
for(int indexB : setB) {
same = setAList.contains(Math.sqrt(indexB)) ? true : false;
System.out.println(Math.sqrt(indexB) + " " + same);
}
结果如下
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
起初我认为问题可能是因为数据类型,但我已经尝试将double转换为int,但仍然得到相同的结果。setAList.get(5)==sqrd
给出了预期的结果,因为setAList.get(5)
(这是一个int
)转换为double
如果您有
setAList.contains(Math.sqrt(indexB))
,则需要手动执行强制转换:setAList.contains((int)Math.sqrt(indexB))
不是直接的答案,而是避免此类问题的解决方法:
正如在其他答案中所解释的,您的问题属于强制转换问题,因为您必须处理double
和int
值,并且不必面对强制转换问题
避免这种情况的一种方法是将A中的值平方,而不是计算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);
int[]a={121,144,19,161,19,144,19,11};
int[]b={12114641,207361,25921361,20736361};
//制作一个包含b数组中的方块的列表
列表方块=数组。流(b)
.boxed()
.collect(Collectors.toList());
//将B中的所有值平方,
//并检查所有结果值是否存在于方块列表中
boolean same=Arrays.stream(a)//数组a中包含值的流
.map(i->i*i)//包含数组a平方中的值的流
.allMatch(正方形::包含);//减少为布尔值,确保流中的所有值都出现在正方形列表中
System.out.println(相同);
查找精确的浮点值,就像在contains()
中所做的那样,由于浮点值的精度有限,在大多数情况下是一个坏主意;您可以自己试一试,看看哪些数字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);
}
}
for(int i=0;i<100;i++){
最终双r=数学sqrt(i);
最终双s=r*r;
如果(s!=i){
System.out.println(i+“!=”+s);
}
}
(打印出测试的100个数字中的51个不相等的平方根。)您的列表包含整数,您正在检查它是否包含双精度,当然不包含。作为旁注,将
a
中的元素平方并检查它们是否在b
(使用乘法,而不是Math.pow方法,这样只处理int)。是的@Bentaye,这是我现在的第二个选择。我必须删除int[]也被转换为列表,并使用“传统”for loop对其进行操作。@实际上,我刚刚删除了一个说明如何使用流的答案,请参见下文查找精确的浮点值,如contains()中所述由于浮点值的精度有限,大多数情况下这是一个坏主意;您可以自己试试看哪个数字Math.sqrt(number)*Math.sqrt(number)
与number
不同。我尝试过这样做,但问题是,它会忽略小数。比方说,我们将一个元素更改为“132”,其平方根为“11.489125293076057”,省略它的小数将给我们一个期望的结果,但它并不能真正解决问题。也许我需要为这一个寻找另一个解决方法。谢谢Andrew!@iamLinker,那么问题出在哪里?我的目标是使用Math.sqrt()的结果来轻松比较元素a和元素b是否相同,以及“相同”,这里,表示“b”中的元素是“a”平方中的元素,而不考虑顺序。@iamLinker then11.489125293076057
应在列表中定义,而不是11
。使a
和b
adouble[]
谢谢!我必须研究你的答案才能更好地理解。@iamLinker我在代码中添加了注释,如果你没有得到什么,尽管问
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);
}
}