【问题标题】:Can I create a list of array with Arrays.asList?我可以使用 Arrays.asList 创建一个数组列表吗?
【发布时间】:2018-07-18 02:09:26
【问题描述】:

假设我想创建一个包含 Integer[] 数组的列表。但是

Integer[] foo = {1,2,3};
List<Integer[]> bar = Arrays.asList(foo);

第二行无法编译,因为Arrays.asList(foo) 将返回一个包含三个 Integer 元素(即 1、2、3)的 List,而不是一个包含单个 Integer[] 元素的 List。

由于文档将 asList 方法的参数声明为 T 类型的可变参数,我不明白为什么编译器不将第二行解释为给定的 Integer[] 类型的单个参数。如何获取单个数组元素的列表?

List<Integer[]> bar = new ArrayList<Integer[]>(Arrays.asList(foo));

这是我真正想做的,但它也无法编译,原因与我相信的相同。

【问题讨论】:

    标签: java list


    【解决方案1】:

    前几天刚有人问过very similar question,但我想这已经足够不同了,不会重复。您需要显式指定泛型类型才能编译,如下所示:

    Integer[] foo = {1, 2, 3};        
    
    List<Integer[]> list = Arrays.<Integer[]>asList(foo);
    

    【讨论】:

    • 那个问题是关于流的。这个问题绝对没有提及流。在任何宇宙中,这两个问题都不会重复。
    • @Makoto 我在上面提到它不是重复的,但解决方案基本上是相同的。
    • @Makoto 这个问题可以概括为:如何使接受可变参数的工厂方法将数组作为一个显式参数而不是可变参数? 所以对链接问题的引用是有效的,因为问题完全相同。 java 9 中的List.of 也是如此,这就是为什么它是explicitly documented
    • @Makoto 我知道,所以它不是重复的。我要说的是,这是关于可变参数的普遍问题
    • @Dukeling 当然,但是如果不需要,为什么要创建一个新对象呢?为什么要让代码变得不那么清晰和不透明 w.r.t.开发商的初衷?如果我需要一维数组,为什么要创建二维数组?为什么表现力不强?通过方法的泛型类型提示编译器似乎是 IMO 的最佳解决方案。
    【解决方案2】:

    除非您确实需要将元素设置为不同数组的能力,否则您可以使用:

    List<Integer[]> list = Collections.singletonList(foo);
    

    这样更有效,因为它专门用于只保存一个元素:不必创建数组,包含只是检查相等性,大小始终为 1 等等。

    【讨论】:

    • 谢谢!我只需要一个数组的副本,这样就可以了。
    【解决方案3】:

    没有。 Arrays.asList 对当前数组进行投影,并将第一个维度展平为 List。由于您只有一个维度,所有这些元素都会被收集到列表中。

    如果你有Integer[][],你可以做到这一点。

    注意:asList 接受T 的可变参数(所以T...),实际上是T[]。如果你用Integer[][] 代替它,你会得到Integer[],因为Integer[][] 的一维将满足T... 的类型要求。

    【讨论】:

    • 哦...我可以始终将数组作为参数传递,只要参数在其他上下文中为 vararg 吗?它们本质上是一样的吗?
    • @user8931048:是的,vararg 被键入为数组。不过要小心,因为并非所有可变参数消费者都像这个一样宽容。
    • 我想我必须在这方面做更多的研究。谢谢!
    【解决方案4】:

    Java 中的可变参数只是 Java 中的语法糖。所以,两者没有区别。

    Arrays.asList(1,2,3)Arrays.asList(new Integer[]{1,2,3})

    那么你可以像下面这样来解决你的问题。

        Integer[][] foo = {{1,2,3}};
        List<Integer[]> bar = Arrays.asList(foo);
    

    【讨论】:

      【解决方案5】:

      Arrays.asList() 生成作为参数传递的数组的内容列表。如果你需要创建数组列表,你需要传递给这个方法array of arrays(例如Integer[][])。

      当您将 Integer[] 作为参数而不是 Integer[][] 传递给方法时,它会生成该数组的内容列表(在这种情况下,这些是 Integers 而不是 Integers 的数组)。

      【讨论】:

        【解决方案6】:

        将您的数组包装在另一个数组中将实现您想要的:

        Integer[] foo = {1,2,3};
        List<Integer[]> bar = Arrays.asList(new Integer[][]{foo});
        // OR
        Integer[][] foo = {{1,2,3}};
        List<Integer[]> bar = Arrays.asList(foo);
        

        您也可以手动设置第一个元素:(我可能会说这更具可读性,但意见可能会有所不同)

        Integer[] foo = {1,2,3};
        List<Integer[]> bar = new ArrayList<>();
        bar.set(0, foo);
        

        【讨论】:

          猜你喜欢
          • 2020-08-10
          • 1970-01-01
          • 1970-01-01
          • 2022-11-23
          • 1970-01-01
          • 2021-05-03
          • 2019-04-16
          • 1970-01-01
          • 2020-01-12
          相关资源
          最近更新 更多