Java:通用方法-向vararg添加元素
我想在这里这样做,它实际上是有效的,但不知何故,我认为这不是一个好的解决方案:Java:通用方法-向vararg添加元素,java,generics,methods,Java,Generics,Methods,我想在这里这样做,它实际上是有效的,但不知何故,我认为这不是一个好的解决方案: class A5<T> implements A4<T> { private final T[] elements; A5(T... elements) { this.elements = elements; } public <R> A5<R> map(Function<T, R> function)
class A5<T> implements A4<T> {
private final T[] elements;
A5(T... elements) {
this.elements = elements;
}
public <R> A5<R> map(Function<T, R> function) {
List<R> liste = new LinkedList<>();
for (T element : elements) {
liste.add(function.apply(element));
}
Object[] objects = new Object[liste.size()];
int counter = 0;
for (R element : liste) {
objects[counter] = liste.get(counter++);
}
return new A5(objects);
}
}
A5级实现A4{
私有最终T[]元素;
A5(T……要素){
这个元素=元素;
}
公共A5地图(功能){
List liste=new LinkedList();
对于(T元素:元素){
add(function.apply(element));
}
Object[]objects=新对象[liste.size()];
int计数器=0;
for(R元素:liste){
objects[counter]=liste.get(counter++);
}
返回新的A5(对象);
}
}
对我来说,Object[]
是个问题,但我无法创建R[]
数组。有人有解决办法吗?更改CTOR和map的签名不是我想要的。只有车身可以更换。您可以尝试:
public <R> A5<R> map(Function<T, R> function) {
List<R> liste = new LinkedList<>();
for (T element : elements) {
liste.add(function.apply(element));
}
Object[] objects = liste.toArray();
return new A5(objects);
}
公共A5地图(功能){
List liste=new LinkedList();
对于(T元素:元素){
add(function.apply(element));
}
Object[]objects=liste.toArray();
返回新的A5(对象);
}
您可以尝试:
public <R> A5<R> map(Function<T, R> function) {
List<R> liste = new LinkedList<>();
for (T element : elements) {
liste.add(function.apply(element));
}
Object[] objects = liste.toArray();
return new A5(objects);
}
公共A5地图(功能){
List liste=new LinkedList();
对于(T元素:元素){
add(function.apply(element));
}
Object[]objects=liste.toArray();
返回新的A5(对象);
}
不可能
您所能做的最好的事情就是获取函数返回的最不特定类型的对象,并使用它来创建一个新数组。显然,当数组为空或函数返回的值仅为null时,这将不起作用
Set<Class<?>> types = new HashSet<>();
List<R> liste = new LinkedList<>();
for (T element : elements) {
R mapped = function.apply(element);
types.add(mapped.getClass());
liste.add(mapped);
}
Class<?> elementType = getMostUnspecifc(types);
return new A5<R>(liste.toArray((R[]) Array.newInstance(elementType, liste.size()));
Set elementType=getmostunspectic(类型);
返回新的A5(liste.toArray((R[])Array.newInstance(elementType,liste.size());
用辅助方法
static Class<?> getMostUnspecifc(Set<Class<?>> types) {
if (types.isEmpty()) {
return Object.class;
}
Class<?> unspecific = types.iterator().next();
for (Class<?> type : types) {
if (!unspecific.isAssignableFrom(type)) {
unspecific = type;
}
}
return unspecific;
}
静态类GetMostUnSpecific(集合类型:类型){
如果(!unspecific.isAssignableFrom(type)){
非特异性=类型;
}
}
返回不具体;
}
不可能
您所能做的就是获取函数返回的最不特定类型的对象,并使用它来创建一个新数组。显然,当数组为空或函数返回的对象仅为null时,这是行不通的
Set<Class<?>> types = new HashSet<>();
List<R> liste = new LinkedList<>();
for (T element : elements) {
R mapped = function.apply(element);
types.add(mapped.getClass());
liste.add(mapped);
}
Class<?> elementType = getMostUnspecifc(types);
return new A5<R>(liste.toArray((R[]) Array.newInstance(elementType, liste.size()));
Set elementType=getmostunspectic(类型);
返回新的A5(liste.toArray((R[])Array.newInstance(elementType,liste.size());
用辅助方法
static Class<?> getMostUnspecifc(Set<Class<?>> types) {
if (types.isEmpty()) {
return Object.class;
}
Class<?> unspecific = types.iterator().next();
for (Class<?> type : types) {
if (!unspecific.isAssignableFrom(type)) {
unspecific = type;
}
}
return unspecific;
}
静态类GetMostUnSpecific(集合类型:类型){
如果(!unspecific.isAssignableFrom(type)){
非特异性=类型;
}
}
返回不具体;
}
您无法创建泛型数组,因此除非您在类A5
中将T[]
更改为列表
,否则您需要创建一个对象[]
您的代码可以简化一点。您可以使用Java 8流将元素映射并收集到对象[]
,然后将此对象[]
强制转换为R[]
。@SuppressWarnings(“unchecked”)
隐藏未选中强制转换产生的警告:
class A5<T> implements A4<T> {
private final T[] elements;
A5(T... elements) {
this.elements = elements;
}
@SuppressWarnings("unchecked")
public <R> A5<R> map(Function<T, R> function) {
return new A5<>((R[]) Arrays.stream(elements).map(function).toArray());
}
}
A5级实现A4{
私有最终T[]元素;
A5(T……要素){
这个元素=元素;
}
@抑制警告(“未选中”)
公共A5地图(功能){
返回新的A5((R[])数组.stream(elements).map(function.toArray());
}
}
您无法创建泛型数组,因此除非您在类
A5
中将T[]
更改为列表
,否则您需要创建一个对象[]
您的代码可以简化一点。您可以使用Java 8流将元素映射并收集到对象[]
,然后将此对象[]
强制转换为R[]
。@SuppressWarnings(“unchecked”)
隐藏未选中强制转换产生的警告:
class A5<T> implements A4<T> {
private final T[] elements;
A5(T... elements) {
this.elements = elements;
}
@SuppressWarnings("unchecked")
public <R> A5<R> map(Function<T, R> function) {
return new A5<>((R[]) Arrays.stream(elements).map(function).toArray());
}
}
A5级实现A4{
私有最终T[]元素;
A5(T……要素){
这个元素=元素;
}
@抑制警告(“未选中”)
公共A5地图(功能){
返回新的A5((R[])数组.stream(elements).map(function.toArray());
}
}
如果您被允许添加一个ctor,您可以将数据存储在列表中,这样做
class A5<T> implements A4<T> {
private final List<T> elements;
A5(T... elements) {
this.elements = Arrays.asList(elements);
}
private A5(List<T> elements) {
this.elements = elements;
}
public <R> A5<R> map(Function<T, R> function) {
List<R> list = elements.stream().map(function)
.collect(Collectors.toList());
return new A5(list);
}
}
A5级实现A4{
私人最终清单要素;
A5(T……要素){
this.elements=Arrays.asList(元素);
}
专用A5(列表元素){
这个元素=元素;
}
公共A5地图(功能){
List List=elements.stream().map(函数)
.collect(Collectors.toList());
返回新的A5(列表);
}
}
如果您被允许添加一个ctor,您可以将数据存储在列表中,这样做
class A5<T> implements A4<T> {
private final List<T> elements;
A5(T... elements) {
this.elements = Arrays.asList(elements);
}
private A5(List<T> elements) {
this.elements = elements;
}
public <R> A5<R> map(Function<T, R> function) {
List<R> list = elements.stream().map(function)
.collect(Collectors.toList());
return new A5(list);
}
}
A5级实现A4{
私人最终清单要素;
A5(T……要素){
this.elements=Arrays.asList(元素);
}
专用A5(列表元素){
这个元素=元素;
}
公共A5地图(功能){
List List=elements.stream().map(函数)
.collect(Collectors.toList());
返回新的A5(列表);
}
}
旁注:您知道您使用的A4、A5的名称实际上没有什么意义吗?当您在不提供类型参数的情况下实例化A5的对象,并直接使用对象时,为什么要将A5声明为泛型?不更改CTOR,是指不能更改其主体还是签名?或者两者?解释两者Jägermeister我只是不允许在这里提供原始源代码。@N-rG在这种情况下,您需要使用
对象[]
,请参阅我的答案泛型数组通常不好。使用List
。注意:您了解到您使用的A4、A5的名称确实没有什么意义?为什么要声明A5为泛型,然后实例化A5对象而不提供类型参数,直接使用对象?通过不更改电子计算机