Java 从ArrayList返回多个对象类型
基本上我有一个类“a”,其他类,比如说“B”,“C”和“D”扩展。这些类型的对象将具有不一定唯一的字符串名称Java 从ArrayList返回多个对象类型,java,Java,基本上我有一个类“a”,其他类,比如说“B”,“C”和“D”扩展。这些类型的对象将具有不一定唯一的字符串名称 public class A { //some code } public class B extends A { // some code } 所以C&D类也扩展了A,和B类一样 接下来我有一个holder类,它有一个arraylist来保存B、C和D对象(这里没有a对象) 公共类持有者{ 列表容器; 公共持有人(){ container=newarraylist
public class A {
//some code
}
public class B extends A {
// some code
}
所以C&D类也扩展了A,和B类一样
接下来我有一个holder类,它有一个arraylist来保存B、C和D对象(这里没有a对象)
公共类持有者{
列表容器;
公共持有人(){
container=newarraylist();
}
公共getItemByName(字符串s){
//返回s==name的第一个对象,或返回null
}
公共A getItemByType(c类){
//返回与类匹配的第一个对象或返回null
}
}
这些函数可以成功地选择所需的对象,但我需要返回B、C和D类型的对象。有没有办法做到这一点?如果有,怎么做?它们不会被类型化为B、C或D对象,因为集合被类型化为a数组。如果不是这样的话,您可能会有一个神奇的类型检查器,因为它必须在编译时知道在运行时会发生什么,或者您可能会遇到矛盾。只需将对象强制转换为afterwords,或者创建一个重写函数,在B、C和D对象上执行它应该执行的操作 考虑以下代码:
A [] aarray = {B1, C1, D1, B2, B3 };
if(theMoonIsFull) { aarray[3+one()] = C2; } // if the moon is full
B hopeitsaB = aarray[4]; // this line doesn't compile
你能行
public <T extends A> T getItemByType(Class<T> c) {
for(Object o : container){
if(c.isInstance(o)){
return c.cast(o);
}
}
return null;
}
以下方法可用于根据
getName()
或提供的类型(Class
)筛选出对象
public一个getItemByName(字符串s){
返回container.stream()
.filter(obj->s.equals(obj.getName()))
.findFirst()
.orElse(空);
}
公共T getItemByType(c类){
返回container.stream()
.过滤器(c::isInstance)
.map(c::cast)
.findFirst()
.orElse(空);
}
这将Java 8流与
可选类一起使用。我强烈建议不要从方法中返回空值,而可以使用可选的类来避免空检查的易出错代码。如果您有一个用于保存不同(和不相关)类型的对象的集合,然后,一个优雅的解决方案可能是将您的容器实现为类型安全的异构容器(有效的Java.Item#29.J.Bloch,第2版)。您可能可以通过方法引用c::isInstanceof
替换筛选器lambda,如果执行返回流…findFirst().orElse(null),则可以去掉if-then-else
.Thx@EdwinDalorzo-它已经更新(c::isInstance
和orElse
)现在看起来棒极了。现在简单多了,甚至更容易阅读。
public <T extends A> T getItemByType(Class<T> c) {
for(Object o : container){
if(c.isInstance(o)){
return c.cast(o);
}
}
return null;
}
B found = holder.getItemByType(B.class);
public A getItemByName(String s) {
return container.stream()
.filter(obj -> s.equals(obj.getName()))
.findFirst()
.orElse(null);
}
public <T extends A> T getItemByType(Class<T> c) {
return container.stream()
.filter(c::isInstance)
.map(c::cast)
.findFirst()
.orElse(null);
}