如何根据Java中输入变量的未知列表类型声明变量?

如何根据Java中输入变量的未知列表类型声明变量?,java,declare,variable-types,Java,Declare,Variable Types,如何根据Java中输入变量的未知列表类型声明变量 例如: 如果给定了arr1,则需要(浅层)从arr1复制到arr2。但您不知道arr1是什么类型的列表 这是我使用的代码,如果我想声明arr2,我必须检查列表类型的所有可能情况 静态列表函数(列表arr1、列表arr2){ if(ArrayList的arr1实例){ arr2=新的ArrayList(arr1); }else if(链接列表的arr1实例){ arr2=新链接列表(arr1); }否则如果(…){ ; } 返回arr2; } 有

如何根据Java中输入变量的未知列表类型声明变量

例如:

如果给定了arr1,则需要(浅层)从arr1复制到arr2。但您不知道arr1是什么类型的列表

这是我使用的代码,如果我想声明arr2,我必须检查列表类型的所有可能情况

静态列表函数(列表arr1、列表arr2){
if(ArrayList的arr1实例){
arr2=新的ArrayList(arr1);
}else if(链接列表的arr1实例){
arr2=新链接列表(arr1);
}否则如果(…){
;
}
返回arr2;
}
有没有更简单的方法根据arr1的类型声明arr2

也许只是看起来像::

需要静态列表(列表arr1、列表arr2){
arr2=新的XXXList(arr1);//其中XXXList基于arr1所在的列表类型
返回arr2;
}

除非我完全误解了您的问题,否则这就是您需要的(Java 8)

公共类ListCopyDemo{
公共静态void main(字符串[]args){
List original=新的ArrayList();
原创。添加(“你好,世界!”);
添加(“欢迎使用Java”);
List copy=ListCopyDemo.funcOri(原件);//应返回原件的副本
}
公共静态列表funcOri(列表arr1){
返回arr1.stream().collect(Collectors.toList());
}
}

如果要将
original
List类型更改为
List
LinkedList
,则
functori
将起到相同的作用。

您始终可以尝试使用反射创建arr1类的新实例

public class ListClone {

    public static void main(String[] args) throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
        List<String> al = new ArrayList<>();
        al.add("abc");

        List<String> ll = new LinkedList<>();
        ll.add("123");

        List<String> alc = funcOri(al);
        List<String> llc = funcOri(ll);

        System.out.println(alc.getClass().getSimpleName());
        System.out.println(llc.getClass().getSimpleName());

        alc.add("def");
        llc.add("456");

        System.out.println(al);
        System.out.println(alc);

        System.out.println(ll);
        System.out.println(llc);
    }

    static <T> List<T> funcOri(List<T> arr1) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        Constructor<? extends List> constructor = arr1.getClass().getConstructor(Collection.class);
        constructor.setAccessible(true);
        return constructor.newInstance(arr1);
    }
}
编辑


这假设arr1的列表类型有一个构造函数来获取集合。当然,完全有可能有列表实现没有。一个稍微安全一点的解决方案可能是使用默认构造函数并使用List.addAll()复制内容,但我们仍然不能确定所有列表实现是否都有默认构造函数。然后它将抛出NoSuchMethodException。

您不需要重新创建
arr2=new ArrayList(arr1)
,因为它已经是ArrayList了。通常,arr1的确切列表类型是不相关的。如果您需要arr1的副本,关于arr2的实际列表类型的决定应基于您将如何使用arr2,即如果您将在任意位置插入项目,则LinkedLisr可能更好。但在大多数情况下,ArrayList已经足够好了。如果确实需要提供复制对象的同一类,可以使用
clone()
方法或反射来创建原始列表的实例:
public static list functori(list original)抛出reflectionOperationException{Objects.requirennull(original);List copy=original.getClass().getDeclaredConstructor().newInstance();copy.addAll(original);return copy;}
此实现不保证
funcOri
返回与输入
arr1
中完全相同的列表实现:这不是我想要的。返回值是一个数组列表。我尝试了以下操作:``公共静态void main(String[]args){List al=new ArrayList();al.add(“abc”);List ll=new LinkedList();ll.add(“123”);List alc=funcOri(al);List llc=funcOri(ll);System.out.println(al.getClass());System.out.println(ll.getClass();System.out.println(alc.getClass());System.out.println(llc.getClass());}```
public class ListClone {

    public static void main(String[] args) throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
        List<String> al = new ArrayList<>();
        al.add("abc");

        List<String> ll = new LinkedList<>();
        ll.add("123");

        List<String> alc = funcOri(al);
        List<String> llc = funcOri(ll);

        System.out.println(alc.getClass().getSimpleName());
        System.out.println(llc.getClass().getSimpleName());

        alc.add("def");
        llc.add("456");

        System.out.println(al);
        System.out.println(alc);

        System.out.println(ll);
        System.out.println(llc);
    }

    static <T> List<T> funcOri(List<T> arr1) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        Constructor<? extends List> constructor = arr1.getClass().getConstructor(Collection.class);
        constructor.setAccessible(true);
        return constructor.newInstance(arr1);
    }
}
ArrayList
LinkedList
[abc]
[abc, def]
[123]
[123, 456]