从包含泛型 类 的列表中流利地迭代到数组
Fluent Iterable to array from a list that contain generic classes
我有以下 class 结构:
abstract class Role;
class Employee extends Role;
class Student extends Role;
class Employer extends Role;
我还有一个枚举,我在其中存储可接受的角色。
public enum RoleEnum
{
EMPLOYEE ("Employee", Employee.class),
STUDENT ("Student", Student.class),
EMPLOYER ("Employer", Employer.class);
final private String name;
final private Class<? extends Role> pRoleClass;
private RoleEnum(final String name, final Class<? extends Role> pRoleClass)
{
this.name = name;
this.pRoleClass = pRoleClass;
}
}
我想要的是从 RoleEnums 列表中获取类型为 Class<? extends Role>
的元素数组。我正在使用 Guava 库中的 FluentIterable,我想做的是 FluentIterable.from(list).transform(function).toArray(Class<? extends PartyRole>)
。然而,我设法做的是一种解决方法,有点像 hack。它看起来像这样:
(Class<R>[]) FluentIterable.from(roles)
.transform(new Function<RoleEnum, Class<R>>()
{
@Override public Class<R> apply(final RoleEnum role)
{
return (Class<R>) role.getRoleClass();
}
})
.toList().toArray(new Class[0]));
哪里
class RoleComboWidget<R extends Role>
是我调用方法的 class 和
ImmutableList<RoleEnum> roles;
你看到的是数组结合泛型的效果。 Java 中的数组在运行时是完全类型化的: 组件类型 在运行时可用,并且 load/store 操作经过类型检查,可能会抛出异常。
这要求 组件类型 是 可具体化的类型 ,但像 RoleComboWidget<W>
这样的参数化类型不是。泛型在 Java 中通过在编译时添加的不可见强制转换实现,但是一旦程序是 运行 JVM 实际上不知道它是 List<String>
还是 List<Integer>
.
回到你的问题,如果你能控制 API,在需要数组而不是 Collection(或 Stream)时要小心:很少有好处(通常在性能上)胜过缺点(通常在源代码维护)。另外,请注意(编译已经警告过你)到 SomeParameterizedType<T>[]
的转换总是未经检查的:根据前面解释的事情,你最终可能会得到 错误的 的对象可能会搞砸甚至停止您的程序的类型。
我有以下 class 结构:
abstract class Role;
class Employee extends Role;
class Student extends Role;
class Employer extends Role;
我还有一个枚举,我在其中存储可接受的角色。
public enum RoleEnum
{
EMPLOYEE ("Employee", Employee.class),
STUDENT ("Student", Student.class),
EMPLOYER ("Employer", Employer.class);
final private String name;
final private Class<? extends Role> pRoleClass;
private RoleEnum(final String name, final Class<? extends Role> pRoleClass)
{
this.name = name;
this.pRoleClass = pRoleClass;
}
}
我想要的是从 RoleEnums 列表中获取类型为 Class<? extends Role>
的元素数组。我正在使用 Guava 库中的 FluentIterable,我想做的是 FluentIterable.from(list).transform(function).toArray(Class<? extends PartyRole>)
。然而,我设法做的是一种解决方法,有点像 hack。它看起来像这样:
(Class<R>[]) FluentIterable.from(roles)
.transform(new Function<RoleEnum, Class<R>>()
{
@Override public Class<R> apply(final RoleEnum role)
{
return (Class<R>) role.getRoleClass();
}
})
.toList().toArray(new Class[0]));
哪里
class RoleComboWidget<R extends Role>
是我调用方法的 class 和
ImmutableList<RoleEnum> roles;
你看到的是数组结合泛型的效果。 Java 中的数组在运行时是完全类型化的: 组件类型 在运行时可用,并且 load/store 操作经过类型检查,可能会抛出异常。
这要求 组件类型 是 可具体化的类型 ,但像 RoleComboWidget<W>
这样的参数化类型不是。泛型在 Java 中通过在编译时添加的不可见强制转换实现,但是一旦程序是 运行 JVM 实际上不知道它是 List<String>
还是 List<Integer>
.
回到你的问题,如果你能控制 API,在需要数组而不是 Collection(或 Stream)时要小心:很少有好处(通常在性能上)胜过缺点(通常在源代码维护)。另外,请注意(编译已经警告过你)到 SomeParameterizedType<T>[]
的转换总是未经检查的:根据前面解释的事情,你最终可能会得到 错误的 的对象可能会搞砸甚至停止您的程序的类型。