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

7qhs6swi  于 2021-06-29  发布在  Java
关注(0)|答案(2)|浏览(411)

如何根据java中输入变量的未知列表类型声明变量?
例如::
你得到了arr1,你需要从arr1复制到arr2。但你不知道arr1是什么类型的列表。
这是我使用的代码,如果我想声明arr2,我必须遍历列表类型的所有可能情况。

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

有没有更简单的方法根据arr1的类型声明arr2?
也许只是看起来像:

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

yqlxgs2m1#

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

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

如果你要改变 original 列表类型到 List<Integer> 或者 LinkedList<String> ,的 funcOri 也一样。

nzk0hqpo

nzk0hqpo2#

您可以尝试使用反射创建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);
    }
}

输出:

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

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

相关问题