【问题标题】:cast List<Object> to List<Map<String, Object>> [duplicate]将 List<Object> 转换为 List<Map<String, Object>> [重复]
【发布时间】:2016-08-15 22:34:56
【问题描述】:

我应该知道这一点,但由于某种原因我无法理解。

为什么我不能将对象列表List&lt;Object&gt; 转换为地图列表List&lt;Map&lt;String, Object&gt;&gt;?列表中的每个对象都是Map&lt;String, Object&gt; 类型的对象,那么为什么不能进行强制转换呢?

我能做的是创建一个new ArrayList&lt;Map&lt;String, Object&gt;&gt;(); 并遍历列表并添加带有演员表的每个项目。

List<Object> dataList;
..
//Why doesn't this work?
List<Map<String, Object>> rxData = (List<Map<String, Object>>)dataList;

//This works, but is there a better way?
rxData = new ArrayList<Map<String, Object>>();
for (Object data : dataList) {
    rxData.add((Map<String, Object>)data);
}

【问题讨论】:

  • 为什么?因为 Java 的泛型是不可重构的。 JVM 无法真正检查演员阵容是否正确。如果你只是想这样做,我认为@SuppressWarnings("unchecked") 是解决方案,虽然我没有测试过。
  • Java 泛型常见问题解答:angelikalanger.com/GenericsFAQ/FAQSections/…?

标签: java hashmap


【解决方案1】:

你可以通过双重转换来删除泛型参数:

@SuppressWarnings("‌​unchecked")
List<Map<String, Object>> rxData = 
    (List<Map<String, Object>>) (List<?>) dataList;

这里发生的情况是,您强制编译器不检查泛型类型,方法是在第一次强制转换时省略它,然后对List&lt;Map&lt;String, Object&gt;&gt; 进行未经检查的强制转换。这是可能的,因为 java 泛型不是refiable

原来的错误是因为ObjectMap&lt;&gt; 类型不兼容,并且java 中没有协变/逆变类型之类的东西(不像scala 例如) .

但是如果dataList 不包含地图就会出现问题。

【讨论】:

  • 这里不需要原始类型,问题与reifiablity无关。
  • @k5_ 同意。谢谢!但无论如何,这将是未经检查的演员。我会编辑我的答案
  • 谢谢!好的,我想我明白了,我需要小心,以便该列表不包含地图以外的任何内容。
  • 您应该删除答案的第一句话,或者在答案的后面移动它:这是真的,但不是很相关。 (不可重构性是为什么从List&lt;?&gt;List&lt;Map&lt;String, Object&gt;&gt; 的转换未被选中;但这与为什么不能从List&lt;Object&gt; 转换到List&lt;Map&lt;String, Object&gt;&gt; 无关。)
  • @ruakh 你是对的。谢谢!我会编辑我的答案
【解决方案2】:

List&lt;Object&gt;List&lt;Map&lt;String, Object&gt;&gt; are not compatible types,因此您不能直接将一个转换为另一个。您必须先转换为一个共同的超类型,然后再向下转换:

List<Map<String, Object>> rxData = (List<Map<String, Object>>)(List<?>)dataList;

请注意,您仍然会在编译时收到警告,因为它是 unsafe cast

【讨论】:

    【解决方案3】:

    查看以下链接

    https://docs.oracle.com/javase/tutorial/java/generics/inheritance.html

    两个泛型类 Type1 和 Type2 根本不相关。因此,您不能将一个类型转换为另一个。

    但是你可以做一些不安全的操作来避免循环。

    //unsafe assignments
    List rxData = (List<Map<String, Object>>)dataList;
    
    List<Object> dataList = (List<Object>)rxData;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-11-23
      • 1970-01-01
      • 2015-11-21
      • 1970-01-01
      • 1970-01-01
      • 2018-09-22
      • 2018-08-15
      相关资源
      最近更新 更多