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对象而不提供类型参数,直接使用对象?通过不更改电子计算机