例如,假设你有两个类:
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>。
当前回答
在Java 8中,实际上可以做到
List<TestB> variable = collectionOfListA
.stream()
.map(e -> (TestB) e)
.collect(Collectors.toList());
其他回答
很奇怪,手动强制转换列表仍然没有提供一些实现如下功能的工具箱:
@SuppressWarnings({ "unchecked", "rawtypes" })
public static <T extends E, E> List<T> cast(List<E> list) {
return (List) list;
}
当然,这不会逐个检查项,但如果我们清楚地知道我们的实现只提供子类型,那么这正是我们在这里要避免的。
当您强制转换对象引用时,您只是强制转换引用的类型,而不是对象的类型。强制转换不会改变对象的实际类型。
Java没有转换对象类型的隐式规则。(与原语)
相反,您需要提供如何将一种类型转换为另一种类型并手动调用它。
public class TestA {}
public class TestB extends TestA{
TestB(TestA testA) {
// build a TestB from a TestA
}
}
List<TestA> result = ....
List<TestB> data = new List<TestB>();
for(TestA testA : result) {
data.add(new TestB(testA));
}
这比在有直接支持的语言中更冗长,但它是可行的,您不需要经常这样做。
我知道的唯一方法就是复制:
List<TestB> list = new ArrayList<TestB> (
Arrays.asList (
testAList.toArray(new TestB[0])
)
);
我必须用公司系统的方法来实现:
interface MyInterface{}
Class MyClass implements MyInterface{}
该方法接收一个接口列表,也就是说,我已经实例化了一个接口列表
private get(List<MyInterface> interface) {
List<MyClass> myClasses = interface.stream()
.filter(MyClass.class::isInstance)
.map(MyClass.class::cast)
.collect(Collectors.toList());
}
您可以在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的提交者。