【问题标题】:Java ArrayList contains method does not identify integer data typeJava ArrayList contains 方法不识别整数数据类型
【发布时间】:2020-09-30 13:40:28
【问题描述】:

我正在创建一个包含字符串和整数混合数据类型的 ArrayList。然后我使用 contains 方法来识别和打印特定成员。尽管 contains 方法识别字符串,但它似乎无法识别列表中存在的整数值。如何检查混合类型列表中的整数值?

代码:

public class ArrayListClass {

    public static void main(String[] args) {
        ArrayList mixArrayList = new ArrayList();

        ArrayListClass ArrayListObj = new ArrayListClass();
        mixArrayList.add("Alpha");
        mixArrayList.add("Beta");
        mixArrayList.add("Gamma");
        mixArrayList.add("Delta");
        mixArrayList.add(1);
        mixArrayList.add(2L);
        mixArrayList.add(3.0);
        mixArrayList.add(4F);
        mixArrayList.add(ArrayListObj);

        System.out.println("mixArrayList is "+ mixArrayList);

        if (mixArrayList.contains(2)) {
            System.out.println("List contains 2");
        }
        else{
            System.out.println("List does not contain 2");
        }
        if ((mixArrayList.contains("Gamma"))) {
            System.out.println("List contains Gamma");
        }
        else{
            System.out.println("List does not contain Gamma");
        }
    }
}

输出:

===========
mixArrayList is [Alpha, Beta, Gamma, Delta, 1, 2, 3.0, 4.0, ArrayListPractice.ArrayListClass@b4c966a]
List does not contain 2
List contains Gamma

Process finished with exit code 0

【问题讨论】:

  • 您添加到列表中的是 Long2,而不是 Integer
  • 很明显,您要添加 2L(长整数)并检查 2(整数)。您不应使用原始形式的 ArrayList 或任何集合 API 以避免运行时问题。
  • 您的mixedArrayList 仍应声明为List<Object> mixedArrayList = new ArrayList<>();
  • 学习使用 Java 命名约定来获取可读代码。对象引用变量应以第一个小写字母命名,而不是ArrayListObj
  • 老实说,拥有混合类型列表是一种代码味道。

标签: java arraylist contains


【解决方案1】:

列表是通用类。请参阅 Oracle 的 Tutorial

所以当你执行以下操作时:

List<Object> list = new ArrayList<>();
list.add(2L);

2LboxesLong,而 2 框为 Integer

所以list.contains(2) 会查找Integer,因此找不到您的2L 条目。

【讨论】:

  • 谢谢。我不知何故认为这些类型可以互换用于少量。但我错了。
  • 你能否解释一下为什么我应该使用 List mixArrayList= new ArrayList();而不是我使用的 ArrayList mixArrayList = new ArrayList();。它似乎是这样工作的。我可能遗漏了一些东西,但只是想知道指定一种方式而不是另一种方式的区别。我是 Java 新手。
  • 有时,即使您不符合推荐的做法,您的代码也可以在 Java 中运行。线程就是一个很好的例子。查看此答案,了解为什么不应使用原始类型。 stackoverflow.com/questions/2770321/…
【解决方案2】:

这是因为22L不一样。

【讨论】:

  • 现在知道了。谢谢。
【解决方案3】:

我在本地 Scala REPL 中尝试了几件事:

scala> val num = new java.lang.Integer(2)
num: Integer = 2

scala> val sameNum = new java.lang.Long(2)
sameNum: Long = 2

scala> num.equals(sameNum)
res0: Boolean = false

scala> sameNum.equals(num)
res1: Boolean = false

这是相关的,因为ArrayList&lt;E&gt;.contains(Object key) 调用indexOf(Object key) 并在给出大于-1 的任何值时返回true,然后indexOf() 又调用equals()key 的类(或该类的超类)定义班级)。至少在 Java 8 中是这样的;我怀疑它已经改变了。

Integer.equals(Object other) 检查otherInteger 的一个实例,Long.equals(Object other) 检查other 是一个Long 的实例。它们都是Number 的直接子类,因此equals() 不会将其中一个实例识别为另一个实例。

我想如果你真的想要,你可以制作自己的 JDK 版本,其中 Number 的每个子类定义 equals() 以取消装箱保存的值,如果 otherNumber 的任何实例并且将它们作为基元进行比较。毕竟,

scala> 2 == 2L
res7: Boolean = true

scala> /* and... */ 2L == 2
res8: Boolean = true

在问自己“我到底需要这个做什么?”之后,我可能很快就会放弃重写 JDK 的想法了。

【讨论】:

    猜你喜欢
    • 2020-01-11
    • 2014-08-20
    • 1970-01-01
    • 2016-10-18
    • 1970-01-01
    • 1970-01-01
    • 2017-07-06
    • 2021-01-23
    • 1970-01-01
    相关资源
    最近更新 更多