将 List<Object[]> 转换为 List<Integer> 时出现歧义
Ambiguities while converting List<Object[]> to List<Integer>
我们尝试使用 hibernate
通过 SQL
查询从数据库中获取结果,如果存在记录,这将 return List<Object[]>
。但是后面我们想把它转换成一个List<Integer>
。因此,我们没有遍历 Object[]
列表并继续添加到整数列表,而是尝试了一些方法,示例代码类似于
public class ListObjectArrayToListInteger {
public static void main(String[] args) {
Object[] ob1 = {1};
Object[] ob2 = {5};
Object[] ob3 = {9};
List objList = new ArrayList();
objList.add(ob1);
objList.add(ob2);
objList.add(ob3);
//Case - 1
List<Integer> intList = objList;
System.out.println(intList);
//Case - 2
List<Integer> intList = new ArrayList<Integer>();
intList.addAll(objList);
System.out.println(intList);
}
}
我们只是试图从查询中获取一列,这就是为什么所有 Arrays
都只有一个元素的原因。 Case-1 和 Case-2 都是分别执行的,两种情况下的输出都是一样的,就像这样
[[Ljava.lang.Object;@3e25a5, [Ljava.lang.Object;@19821f,
[Ljava.lang.Object;@addbf1]
在 Case-1 intList
中,List<Integer>
的类型指向 List
的对象 Object[]
秒。我们期望在 运行 时间内出现异常,因为数据类型完全不同。
在 Case-2 中,我们明确地将 Object[]
s 添加到 List<Integer>
并且毫无例外地给出了据我所知的输出奇怪。
- 那么谁能解释为什么我们会得到这样的输出?
- 一个
List<Integer>
,在它的所有位置只期望 Integers
,如何保存这样的数据 [[Ljava.lang.Object;@3e25a5, [Ljava.lang.Object;@19821f]
?
- 为什么 Java 允许用户将数据从原始数据列表添加到通用列表。在我的代码中,如果我使
Object[] ob1 = {1, 2, "3", "abc"};
它可以添加到 intList
作为 intList.addAll(objList);
这是允许的并且 运行s 顺利。
在休眠状态下,数组中的每个对象都代表一个选定的实体 (table)。
最好将查询限制为所需的结果:
String hql = "select count(me.grp) from MyEntity me group by grp";
TypedQuery<Integer> query = entityManager.createQuery(hql, Integer.class);
List<Integer> result = query.getResult();
假设您也需要扩展数据用于其他目的:
List<Integer> result = objList.stream()
.map(oarr -> oarr[0])
.map(Integer.class::cast)
.collect(Collectors.toList());
对于休眠查询 select A a, B b, C c
不是 int,而是 class A:
List<Object[]> objList = ...
List<Integer> result = objList.stream()
.map(oarr -> oarr[0]) // Object[] to Object
.map(A.class::cast) // Object to A
.map(A::getId) // A to int A.getId()
.collect(Collectors.toList());
上代码
如果键入 objList,它将不会编译。
List<Object[]> objList = new ArrayList<>();
如果没有类型参数,整个泛型类型就不会适用于 objList
,因此甚至适用于 intList
。使用类型擦除 intList
只是一个对象列表,并且一切正常。
@A运行 Sudhakaran,你问的三个问题可以这样回答:
问题一:
案例一:
你说:intList
List<Integer>
的类型指向 List
的 Object[]
对象s ".
这是不正确的,因为您没有使用参数 <Object[]>
初始化 objList
;您正在像这样初始化 objList
:List objList = new ArrayList();.
这样,objList
将创建为 List
和 raw-type,而不是 List
输入 Object[]
.
(更多关于 raw-type: https://docs.oracle.com/javase/tutorial/java/generics/rawTypes.html)
因为 intList
是 List<Integer>
的类型,这意味着 intList
指向 List
的对象 raw-type- 不是类型为 Object[]
s.List
的对象。
自 JDK 1.5 以来,泛型一直是 Java 的一部分。为了保持向后兼容性,Java 没有删除使用 raw-type.
的集合初始化
//Case - 1
List<Integer> intList = objList;
在这种情况下,objList
被初始化为 raw-type。通过将 intList
指向 objList
,编译器不知道 objList
集合变量持有的值的类型。这就是编译器允许您将 Object
的数组添加到 objList
.
的原因
案例二:
//Case - 2
List<Integer> intList = new ArrayList<Integer>();
intList.addAll(objList);
System.out.println(intList);
你说:" 我们明确地向 List<Integer>
添加了 Object[]
s 并且毫无例外地给出了输出 "
同样,这是不正确的。您正在将 Object[]
类型的 List
添加到 List<Integer>
中,而不是将 Object[]
类型添加到 List<Integer>
中。你不是在做 intList.add(ob1); intList.add(ob2);
。如果你这样做,那么你可以说我们正在将 Object[]
s 添加到 List<Integer>
.
从 JDK 1.5 开始,您可以使用泛型来初始化集合变量,如下所示:
List<Integer> list = new ArrayList<>(); //or
List<?> list = new ArrayList<>();
之后,当尝试将元素添加到 list
时,编译器将检查元素是否具有与 list
相同的数据类型或与 [=46] 相同的 sub-type =].当您将鼠标悬停在 IDE(如 eclipse 或 intelliJ)中的集合变量上时,您可能会看到类似 List<? extends Integer>
.
的内容
但是这里,objList
是用 raw-type 初始化的,不是泛型。这意味着编译器不知道 objList
不是 Integer
或 sub-type Integer
类型。如果是这种情况,编译器将不会抛出异常。相反,编译器会遍历列表并给出ob1
、ob2
和`ob3.
的引用值
问题二:
当试图将 objList
的所有元素添加到 List<Integer>
时,在编译时,编译器将不知道 objList
的 data-type 因为 objList
属于raw-type。因此,编译器不会抛出异常。相反,编译器将允许用户将此类元素添加到 List<Integer>
中。当尝试遍历 List<Integer>
时,您会发现 objList
中元素的参考值是 ob1
、ob2
和 ob3
.
问题三:
Java 只允许用户将原始数据列表中的数据添加到通用列表中。这样做是为了支持 兼容性 ,这也是您的代码在 JDK 1.4 和 运行 中顺利 运行 的原因=107=]JDK 1.8 无需更改任何代码。
我们尝试使用 hibernate
通过 SQL
查询从数据库中获取结果,如果存在记录,这将 return List<Object[]>
。但是后面我们想把它转换成一个List<Integer>
。因此,我们没有遍历 Object[]
列表并继续添加到整数列表,而是尝试了一些方法,示例代码类似于
public class ListObjectArrayToListInteger {
public static void main(String[] args) {
Object[] ob1 = {1};
Object[] ob2 = {5};
Object[] ob3 = {9};
List objList = new ArrayList();
objList.add(ob1);
objList.add(ob2);
objList.add(ob3);
//Case - 1
List<Integer> intList = objList;
System.out.println(intList);
//Case - 2
List<Integer> intList = new ArrayList<Integer>();
intList.addAll(objList);
System.out.println(intList);
}
}
我们只是试图从查询中获取一列,这就是为什么所有 Arrays
都只有一个元素的原因。 Case-1 和 Case-2 都是分别执行的,两种情况下的输出都是一样的,就像这样
[[Ljava.lang.Object;@3e25a5, [Ljava.lang.Object;@19821f, [Ljava.lang.Object;@addbf1]
在 Case-1 intList
中,List<Integer>
的类型指向 List
的对象 Object[]
秒。我们期望在 运行 时间内出现异常,因为数据类型完全不同。
在 Case-2 中,我们明确地将 Object[]
s 添加到 List<Integer>
并且毫无例外地给出了据我所知的输出奇怪。
- 那么谁能解释为什么我们会得到这样的输出?
- 一个
List<Integer>
,在它的所有位置只期望Integers
,如何保存这样的数据[[Ljava.lang.Object;@3e25a5, [Ljava.lang.Object;@19821f]
? - 为什么 Java 允许用户将数据从原始数据列表添加到通用列表。在我的代码中,如果我使
Object[] ob1 = {1, 2, "3", "abc"};
它可以添加到intList
作为intList.addAll(objList);
这是允许的并且 运行s 顺利。
在休眠状态下,数组中的每个对象都代表一个选定的实体 (table)。
最好将查询限制为所需的结果:
String hql = "select count(me.grp) from MyEntity me group by grp";
TypedQuery<Integer> query = entityManager.createQuery(hql, Integer.class);
List<Integer> result = query.getResult();
假设您也需要扩展数据用于其他目的:
List<Integer> result = objList.stream()
.map(oarr -> oarr[0])
.map(Integer.class::cast)
.collect(Collectors.toList());
对于休眠查询 select A a, B b, C c
不是 int,而是 class A:
List<Object[]> objList = ...
List<Integer> result = objList.stream()
.map(oarr -> oarr[0]) // Object[] to Object
.map(A.class::cast) // Object to A
.map(A::getId) // A to int A.getId()
.collect(Collectors.toList());
上代码
如果键入 objList,它将不会编译。
List<Object[]> objList = new ArrayList<>();
如果没有类型参数,整个泛型类型就不会适用于 objList
,因此甚至适用于 intList
。使用类型擦除 intList
只是一个对象列表,并且一切正常。
@A运行 Sudhakaran,你问的三个问题可以这样回答:
问题一:
案例一:
你说:intList
List<Integer>
的类型指向 List
的 Object[]
对象s ".
这是不正确的,因为您没有使用参数 <Object[]>
初始化 objList
;您正在像这样初始化 objList
:List objList = new ArrayList();.
这样,objList
将创建为 List
和 raw-type,而不是 List
输入 Object[]
.
(更多关于 raw-type: https://docs.oracle.com/javase/tutorial/java/generics/rawTypes.html)
因为 intList
是 List<Integer>
的类型,这意味着 intList
指向 List
的对象 raw-type- 不是类型为 Object[]
s.List
的对象。
自 JDK 1.5 以来,泛型一直是 Java 的一部分。为了保持向后兼容性,Java 没有删除使用 raw-type.
的集合初始化//Case - 1
List<Integer> intList = objList;
在这种情况下,objList
被初始化为 raw-type。通过将 intList
指向 objList
,编译器不知道 objList
集合变量持有的值的类型。这就是编译器允许您将 Object
的数组添加到 objList
.
案例二:
//Case - 2
List<Integer> intList = new ArrayList<Integer>();
intList.addAll(objList);
System.out.println(intList);
你说:" 我们明确地向 List<Integer>
添加了 Object[]
s 并且毫无例外地给出了输出 "
同样,这是不正确的。您正在将 Object[]
类型的 List
添加到 List<Integer>
中,而不是将 Object[]
类型添加到 List<Integer>
中。你不是在做 intList.add(ob1); intList.add(ob2);
。如果你这样做,那么你可以说我们正在将 Object[]
s 添加到 List<Integer>
.
从 JDK 1.5 开始,您可以使用泛型来初始化集合变量,如下所示:
List<Integer> list = new ArrayList<>(); //or
List<?> list = new ArrayList<>();
之后,当尝试将元素添加到 list
时,编译器将检查元素是否具有与 list
相同的数据类型或与 [=46] 相同的 sub-type =].当您将鼠标悬停在 IDE(如 eclipse 或 intelliJ)中的集合变量上时,您可能会看到类似 List<? extends Integer>
.
但是这里,objList
是用 raw-type 初始化的,不是泛型。这意味着编译器不知道 objList
不是 Integer
或 sub-type Integer
类型。如果是这种情况,编译器将不会抛出异常。相反,编译器会遍历列表并给出ob1
、ob2
和`ob3.
问题二:
当试图将 objList
的所有元素添加到 List<Integer>
时,在编译时,编译器将不知道 objList
的 data-type 因为 objList
属于raw-type。因此,编译器不会抛出异常。相反,编译器将允许用户将此类元素添加到 List<Integer>
中。当尝试遍历 List<Integer>
时,您会发现 objList
中元素的参考值是 ob1
、ob2
和 ob3
.
问题三:
Java 只允许用户将原始数据列表中的数据添加到通用列表中。这样做是为了支持 兼容性 ,这也是您的代码在 JDK 1.4 和 运行 中顺利 运行 的原因=107=]JDK 1.8 无需更改任何代码。