初始化 ArrayList<Long>

15

为什么我可以像这样初始化ArrayList:

ArrayList<Integer> x = new ArrayList<Integer>(Arrays.asList(1,2));

但在使用时遇到错误:

ArrayList<Long> x = new ArrayList<Long>(Arrays.asList(1,2));

1
默认情况下,数字是 int 类型的,因此当 Java 尝试自动装箱 1 和 2 时,它将转换为包装类型 Integer,而 Integer 不同于 Long 或者与其无关。 - Ahmad Sanie
5
Arrays.asList(1L, 2L) 的翻译是:将1L和2L以列表的形式放入数组中。 - Schidu Luca
1
1和2是整数,不是长整数。 - XtremeBaumer
4个回答

34

解释

在Java中,如果需要将类型从int转换为long,它会自动进行转换。

但是,如果需要将类型从Integer转换为Long,Java不会自动进行转换。

函数Arrays.asList(...)返回一个具有List<E>类型的列表,其中E是用作参数的类型。由于使用了1, 2, 3,所以类型是int。但是,在Java中,不能以数据类型作为List<int>的泛型使用(至少目前情况下是这样)。因此,它会自动将int转换为Integer并生成一个List<Integer>对象。这个过程称为自动装箱,Java可以将所有数据类型自动转换为它们相应的对象表示形式。

如果现在使用构造函数new ArrayList<Integer>(List<E> list),它期望EInteger类型的。所以List<Integer>作为输入是有效的。

但是,当您使用new ArrayList<Long>(List<E> list)时,显然E需要是Long类型。但是Integer对象不属于Long类型,因此它不接受该参数。 IntegerLong的第一个公共类型是抽象类Number(也包括DoubleFloat等)(文档)。


解决方案

所以问题都围绕着输入的1, 2, 3被解释为int而不是long。你可以通过明确地告诉Java将数字解释为long来解决这个问题,方法是在数字后面添加lL:

new ArrayList<Long>(Arrays.asList(1L, 2L, 3L));

现在你收到一个List<Long>,然后将其添加到一个ArrayList<Long>中。


请注意,同样的技术也可以用来将十进制数明确地解释为float而不是double1.5F1.5f


1
需要注意的是,asList 返回的是一个自定义的固定大小的 ArrayList,而不是 java.util.ArrayList - Oleg
@Oleg 你说得对,我不知道那个。我会从答案中删除这个注释,因为它没有什么用处。 - Zabuzard

13

这是因为12是整数类型(int),而Arrays.asList(1, 2)创建了一个List<Integer>

ArrayList的拷贝构造函数需要传入相同泛型类型的参数。

有几种解决方案,但最简单的方法是将整数类型(int)转换为长整型(long),只需添加后缀L即可:

List<Long> x = new ArrayList<Long>(Arrays.asList(1L, 2L));

请注意,在Java 9中,您也可以编写以下内容:

List<Long> x = List.of(1L, 2L);

1
值得一提的是,Java 9版本类似于Arrays.asList,返回一个不可变的List - 如果您想让x可变,仍然需要使用复制构造函数。 - Hulk
为了避免混淆 - 我知道 Arrays.asList 返回的列表是可变的,但大小固定。这个问题的答案也可能对未来的读者有所帮助。 - Hulk

12

你必须使用字面量 lL 来指定一个 Long 数字。

List<Long> x = new ArrayList<Long>(Arrays.asList(1L, 2L));
否则,12 被理解为整数,导致 List<Integer>

4

由于Arrays.asList(1,2)将隐式返回一个List<Integer>

您可以通过使用以下惯用语来解决此问题:

ArrayList<Long> x = new ArrayList<Long>(Arrays.asList(1l,2l));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接