【问题标题】:List contains method returns false when using Math.sqrt() as a parameter使用 Math.sqrt() 作为参数时,List contains 方法返回 false
【发布时间】:2023-04-04 21:48:33
【问题描述】:

我正在更新我的 Java 知识,并在代码战中进行练习。问题是如果元素“相同”,则比较两个数组。 “相同”的意思是'b'中的元素是'a'中的元素的平方,无论顺序如何。我试图做的解决方案是获取“b”中元素的平方根,并使用 Math.sqrt() 检查它是否存在于元素“a”中。但是,当我将它用作 contains() 的参数时,它总是返回 false。

为了检查元素“b”的平方根是否确实存在于“a”中,我尝试了一个简单的 if-else 来检查特定元素。但是当我将它与 Math.sqrt() 合并时,问题就出现了。

这是集合 a 和 b 的元素

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

我将数组转换为 List 以利用 contains() 方法。 这是我尝试检查特定元素时的代码

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

这给出了预期的结果 - 是的。 现在这是我将它合并到 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,但我仍然得到相同的结果。

【问题讨论】:

  • 您的列表包含整数,您正在检查它是否包含双精度数,当然没有。
  • 附带说明,将a 中的元素平方并检查它们是否在b 中会更容易(使用乘法,而不是 Math.pow 方法,这样你只处理整数)。
  • 是的@Bentaye,这是我现在的第二个选择。我将不得不放弃正在转换为 List 的 int[],并使用“传统”for 循环对其进行操作。
  • @iamLinker 实际上我刚刚放弃了一个答案,展示了如何使用流来做到这一点,见下文
  • 查找 exact 浮点值,就像在 contains() 中所做的那样,由于浮点值的精度有限,大多数情况下是个坏主意;您可以自己尝试一下,看看Math.sqrt( number ) * Math.sqrt( number )number 的哪些数字不同

标签: java arraylist contains math.sqrt


【解决方案1】:

setAList.get(5) == sqrd 为您提供预期结果,因为 the widening primitive conversionsetAList.get(5)(这是一个 int)到 double

如果您有 setAList.contains(Math.sqrt(indexB)),则需要手动进行转换:setAList.contains((int)Math.sqrt(indexB))

【讨论】:

  • 我试过这样做,但问题是,它会省略小数。比方说,我们将一个元素更改为“132”,它的平方根为“11.489125293076057”,省略它的小数会给我们一个想要的结果,但它并不能真正解决问题。好吧,也许我需要为此寻找另一种解决方法。谢谢安德鲁!
  • @iamLinker 那么有什么问题呢?
  • 我的目标是使用 Math.sqrt() 的结果来轻松比较元素 a 是否与元素 b 相同。这里的“相同”意味着“b”中的元素是“a”中的元素的平方,无论顺序如何。
  • @iamLinker 然后11.489125293076057 应该在列表中定义而不是11。将ab 设为double[]
【解决方案2】:

不是直接的答案,而是避免此类问题的解决方法:

正如其他答案中所解释的,您的问题是演员表问题,因为您必须处理 doubleint 值,并且不必面对演员表问题。

避免这种情况的一种方法是对 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);

【讨论】:

  • 谢谢!我必须研究你的答案才能更好地理解。
  • @iamLinker 我在代码里加了cmets,有没有得到就问一下
【解决方案3】:

查找 精确 浮点值,就像在 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);
  }
}

(从测试的 100 个数字中打印出 51 个不等方根。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-04-19
    • 2020-07-18
    • 1970-01-01
    • 1970-01-01
    • 2019-02-18
    • 2017-12-01
    • 2012-11-01
    • 1970-01-01
    相关资源
    最近更新 更多