例如,假设你有两个类:
public class TestA {}
public class TestB extends TestA{}
我有一个返回List<TestB>的方法,我想将该列表中的所有对象强制转换为TestB,以便最终得到List<TestB>。
例如,假设你有两个类:
public class TestA {}
public class TestB extends TestA{}
我有一个返回List<TestB>的方法,我想将该列表中的所有对象强制转换为TestB,以便最终得到List<TestB>。
当前回答
您可以在Eclipse Collections中使用selectInstances方法。这将涉及创建一个新的集合,但不会像使用强制转换的公认解决方案那样有效。
List<CharSequence> parent =
Arrays.asList("1","2","3", new StringBuffer("4"));
List<String> strings =
Lists.adapt(parent).selectInstancesOf(String.class);
Assert.assertEquals(Arrays.asList("1","2","3"), strings);
我在示例中加入StringBuffer是为了说明selectInstances不仅向下转换类型,而且还将过滤集合是否包含混合类型。
注意:我是Eclipse Collections的提交者。
其他回答
如果你有一个类TestA的对象,你不能将它强制转换到TestB。每个TestB都是TestA,而不是相反。
在以下代码中:
TestA a = new TestA();
TestB b = (TestB) a;
第二行将抛出ClassCastException。
如果对象本身是TestB,则只能强制转换TestA引用。例如:
TestA a = new TestB();
TestB b = (TestB) a;
因此,您可能不总是将TestA的列表转换为TestB的列表。
由于类型擦除,这是可能的。你会发现
List<TestA> x = new ArrayList<TestA>();
List<TestB> y = new ArrayList<TestB>();
x.getClass().equals(y.getClass()); // true
在内部,两个列表的类型都是List<Object>。出于这个原因,你不能将一个转换为另一个——没有什么可以转换的。
很奇怪,手动强制转换列表仍然没有提供一些实现如下功能的工具箱:
@SuppressWarnings({ "unchecked", "rawtypes" })
public static <T extends E, E> List<T> cast(List<E> list) {
return (List) list;
}
当然,这不会逐个检查项,但如果我们清楚地知道我们的实现只提供子类型,那么这正是我们在这里要避免的。
正如Steve Kuo提到的,您不能将List<TestB>转换为List<TestA>,但是您可以将List<TestA>的内容转储到List<TestB>。试试下面的方法:
List<TestA> result = new List<TestA>();
List<TestB> data = new List<TestB>();
result.addAll(data);
我没有尝试过这段代码,所以可能有错误,但其思想是,它应该遍历数据对象,将元素(TestB对象)添加到List中。我希望这对你有用。
最安全的方法是实现AbstractList并在实现中强制转换项。我创建了ListUtil helper类:
public class ListUtil
{
public static <TCastTo, TCastFrom extends TCastTo> List<TCastTo> convert(final List<TCastFrom> list)
{
return new AbstractList<TCastTo>() {
@Override
public TCastTo get(int i)
{
return list.get(i);
}
@Override
public int size()
{
return list.size();
}
};
}
public static <TCastTo, TCastFrom> List<TCastTo> cast(final List<TCastFrom> list)
{
return new AbstractList<TCastTo>() {
@Override
public TCastTo get(int i)
{
return (TCastTo)list.get(i);
}
@Override
public int size()
{
return list.size();
}
};
}
}
您可以使用cast方法盲目地转换列表中的对象,并使用convert方法进行安全转换。 例子:
void test(List<TestA> listA, List<TestB> listB)
{
List<TestB> castedB = ListUtil.cast(listA); // all items are blindly casted
List<TestB> convertedB = ListUtil.<TestB, TestA>convert(listA); // wrong cause TestA does not extend TestB
List<TestA> convertedA = ListUtil.<TestA, TestB>convert(listB); // OK all items are safely casted
}