【问题标题】:Cast ArrayList in Java [duplicate]在 Java 中转换 ArrayList [重复]
【发布时间】:2019-04-30 00:11:55
【问题描述】:

我正在使用两个类

Class TestClassOne{
//Some methods
//Some methods
//Some methods
}

Class TestClassTwo extends TestClassOne{ 
//Some Variable
//Some Variable
//Some Variable
}

现在我有 TestClassOne 对象并且可以转换为 TestClassTwo。

TestClassOne classOne = new TestClassOne();
TestClassTwo classTwo = (TestClassTwo)classOne;

我可以对 ArrayList 做同样的事情吗? 例如

ArrayList<TestClassOne> testList1 = new ArrayList<>();
ArrayList<TestClassTwo> testList2 = (ArrayList<TestClassTwo>) testList1;

但是我收到了无法转换的错误。有没有其他方法可以转换 ArrayList?

【问题讨论】:

  • TestClassOne classOne = new TestClassOne(); TestClassTwo classTow = (TestClassTwo)abstractProfile - 你的意思是投classOne
  • 是的。现在编辑了我的问题。
  • 我很惊讶你能做到TestClassTwo classTow = (TestClassTwo)classOne; 你确定TestClassTow 不会扩展TestClassOne吗?
  • 没有继承怎么能投??我很惊讶。请提供更详细的代码sn-p
  • 两种情况都会出现编译错误

标签: java


【解决方案1】:

泛型类型不能像那样相互转换。 T&lt;A&gt; 不能转换为 T&lt;B&gt;,即使 B 继承自 A

在这种特殊情况下,您可以做的是将数组列表中的每个单独元素强制转换,并使用这些元素创建一个新的数组列表。

ArrayList<TestClassTwo> testList2 = testList1.stream().map(x -> (TestClassTwo)x)
                                             .collect(Collectors.toCollection(ArrayList::new))

显然,这仅在存储在数组列表中的对象实际上都是TestClassTwo 的实例时才有效。

【讨论】:

    【解决方案2】:

    简单转换 TestClassOne-&gt; TestClassTwo 将不起作用,除非您的 testList1 集合包含 TestClassTwo 的实例,并且只有它们。

    您想要实现的铸造是不可能的,因为即使TestClassTwo 扩展TestClassOne,也没有保证,该类TestClassTwo 将有一个足够的构造函数。 TestClassTwo 可能有其他变量,JVM 不知道如何处理。如您所见,即使对人类来说,这也是有问题的。

    ================================================ ============================ 以其他方式铸造是可能的。因为TestClassTwo 将具有与TestClassOne 相同的方法,因为它扩展了它。

    ================================================ ============================ 如果您想在同一个集合中同时保存TestClassOneTestClassTwo 的元素,那么您可以使用通用通配符:

     List<? extends TestClassOne> testList1 = new ArrayList<>();
    

    但是在强制转换之前,您必须检查给定元素是否属于 TestClassTwo 类型。

    TestClassOne one = testLis.get(1);
    if(one instanceOf TestClassTwo.class) {
       (TestClassTwo) one; // handle me
    }
       one; // can't be casted, but can be adapted
    

    ================================================ =============================

    其他解决方案是在TestClassTwo 中使用适配器构造函数。它将接受TestClassOne 作为参数(如果需要,还可以插入其他参数)。 TestClassTwo 对象的创建应由您管理。

    class TestClassTwo extends TestClassOne{ 
    
         TestClassTwo(TestClassOne in) {...}
    }
    

    那么你可以简单地使用适应:

    List<TestClassOne> testList1 = new ArrayList<>();//add some arguments
    List<TestClassTwo> testList2 = testList1.stream().map(TestClassTwo::new).collect(toList());
    

    【讨论】:

      【解决方案3】:

      你可以使用泛型类

      class TestClassOne<T>
      {
      
      }
      class TestClassTwo
      {
      }
      

      像这样投射

      List<TestClassOne<TestClassTwo>> list = new List<TestClassOne<TestClassTwo>>();
      

      【讨论】:

        【解决方案4】:

        你不能。不支持带有类型参数的继承。

        而是创建一个静态辅助方法,它将遍历列表中的一个,并强制转换每个单独的元素,并返回新列表。例如

            public static convert(ArrayList<ClassOne>) {
                ArrayList<ClassTwo> b = new ArrayList<ClassTwo>(); 
                forEach(classOne)  {
                    b.add((ClassTwo)classOne);
                }
                return b;
            }
        

        【讨论】:

          猜你喜欢
          • 2018-04-29
          • 2017-06-02
          • 1970-01-01
          • 1970-01-01
          • 2014-09-23
          • 2014-04-30
          • 1970-01-01
          • 2015-04-23
          • 2019-03-15
          相关资源
          最近更新 更多