简体   繁体   English

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

[英]How to declare a variable according to an unknown List type of the input variable in Java?

How to declare a variable according to an unknown List type of the input variable in Java?如何根据Java中输入变量的未知List类型声明变量?

For example::例如::

You are given arr1, you need to (shallow) copy from arr1 to arr2.给你 arr1,你需要(浅)从 arr1 复制到 arr2。 But you don't know what type of list arr1 is.但是你不知道列表 arr1 是什么类型的。

This is the code that I use, if I want to declare arr2, I have to go through all possible cases of types of List.这是我使用的代码,如果我想声明 arr2,我必须通过所有可能的 List 类型的情况来 go。

  static List<Object> funcOri(List<Object> arr1, List<Object> arr2) {
    if (arr1 instanceof ArrayList<?>) {
      arr2 = new ArrayList<Object>(arr1);
    } else if (arr1 instanceof LinkedList<?>) {
      arr2 = new LinkedList<Object>(arr1);
    } else if (...) {
      ;
    }
    return arr2;
  }

Is there a simpler way to declare arr2 according to the type of arr1 is?根据 arr1 的类型声明 arr2 有没有更简单的方法?

Maybe something that simply looks like::也许只是看起来像::

  static List<Object> funcWanted(List<Object> arr1, List<Object> arr2) {
    arr2 = new XXXList<Object>(arr1); // where XXXList is base on the type of list the arr1 is
    return arr2;
  }

You can always try to create a new instance of arr1's class using reflections.您始终可以尝试使用反射创建 arr1 的 class 的新实例。

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);
    }
}

Output: Output:

ArrayList
LinkedList
[abc]
[abc, def]
[123]
[123, 456]

Edit编辑

This assumes that the list type of arr1 has a constructor to take a Collection.这假设 arr1 的列表类型有一个构造函数来获取一个 Collection。 It's of course entirely possible that there are List implementations that don't.当然,完全有可能存在没有的 List 实现。 A slightly safer solution might be to go for a default constructor and use List.addAll() to copy the contents but we can still not be certain that all List implementations have a default constructor.一个更安全的解决方案可能是将 go 作为默认构造函数并使用 List.addAll() 复制内容,但我们仍然不能确定所有 List 实现都有默认构造函数。 It will then throw NoSuchMethodException.然后它将抛出 NoSuchMethodException。

Unless I am completely misunderstanding your problem, this is what you need (Java 8)除非我完全误解了您的问题,否则这就是您所需要的(Java 8)

public class ListCopyDemo {
    
    public static void main (String[] args) {
        List<String> original = new ArrayList<>();
        original.add("Hello World!");
        original.add("Welcome to Java");
        
        List<?> copy = ListCopyDemo.funcOri(original); // should return a copy of the original
    }
    
    public static List<Object> funcOri(List<?> arr1) {
        return arr1.stream().collect(Collectors.toList());
    }
}

If you were to change original List type to List<Integer> or LinkedList<String> , the funcOri will work the same.如果要将original List 类型更改为List<Integer>LinkedList<String> ,则funcOri的工作方式相同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM