在Java中使用Cast ArrayList

Cast ArrayList in Java

本问题已经有最佳答案,请猛点这里访问。

我用两个班

1
2
3
4
5
6
7
8
9
10
11
Class TestClassOne{
//Some methods
//Some methods
//Some methods
}

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

现在我有了testclassone对象,可以转换为testclass2。

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

我可以为arraylist做同样的操作吗?例如

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

但我得到了无法施展的错误。有没有其他的方法来抛出数组列表?


不能像那样互相转换泛型类型。即使BA继承,T也不能被铸造给T

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

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

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


除非您的testList1集合持有TestClassTwo的实例,并且仅持有这些实例,否则简单的强制转换TestClassOne-> TestClassTwo将不起作用。

您想要实现的强制转换是不可能的,因为即使TestClassTwo扩展了TestClassOne,也没有保证,类TestClassTwo将有一个适当的构造函数。TestClassTwo可能有额外的变量,JVM不知道如何处理这些变量。所以你可以看到,这对人类来说也是个问题。

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

=========================================================如果要在同一个collction中同时保存TestClassOneTestClassTwo的元素,则可以使用通用通配符:

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

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

1
2
3
4
5
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对象应该由您来管理。

1
2
3
4
class TestClassTwo extends TestClassOne{

     TestClassTwo(TestClassOne in) {...}
}

然后您可以使用简单的adapt:

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


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

相反,创建一个静态助手方法,该方法将迭代列表中的一个,并强制转换每个元素,并返回新列表。例如

1
2
3
4
5
6
7
    public static convert(ArrayList<ClassOne>) {
        ArrayList<ClassTwo> b = new ArrayList<ClassTwo>();
        forEach(classOne)  {
            b.add((ClassTwo)classOne);
        }
        return b;
    }

可以使用泛型类

1
2
3
4
5
6
7
class TestClassOne<T>
{

}
class TestClassTwo
{
}

像这样铸造

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