【问题标题】:ArrayList Declaration vs ConversionArrayList 声明与转换
【发布时间】:2015-11-12 14:13:42
【问题描述】:

我对我的 Java 编程非常陌生,并且正在学习 Google 的 Udacity 课程作为进修。我正在学习 Sunshine 应用程序的第 1 课,讲师选择通过声明字符串数组然后将其转换为 ArrayList 来创建假数据。

代码如下:

String[] data = {
            "Mon 6/23 - Sunny - 31/17",
            "Tue 6/24 - Foggy - 21/8",
            "Wed 6/25 - Cloudy - 22/17",
            "Thurs 6/26 - Rainy - 18/11",
            "Fri 6/27 - Foggy - 21/10",
            "Sat 6/28 - TRAPPED IN WEATHERSTATION - 23/18",
            "Sun 6/29 - Sunny - 20/7"
    };
    List<String> weatherForecast = new ArrayList<>(Arrays.asList(data));

我想知道使用这种转换方法有什么好处吗?为什么不立即将数据声明为 ArrayList:

    ArrayList weatherForecast = new ArrayList();
    weatherForecast.add("Today - Sunny - 88/63");
    weatherForecast.add("Tomorrow - Foggy = 70/46");
    weatherForecast.add("Weds - Cloudy - 72/63");
    weatherForecast.add("Thurs 6/26 - Rainy - 18/11");
    weatherForecast.add("Sat 6/28 - TRAPPED IN WEATHERSTATION - 23/18");
    weatherForecast.add("Sun 6/29 - Sunny - 20/7");

谢谢!

【问题讨论】:

  • 也许讲师只是想证明您可以使用 Collections API 在数组和列表之间轻松转换。 ArrayList 在幕后使用了一个数组。在某些情况下(但不是这种情况),您可能会从使用数组中挤出一点性能优势,但列表将提供更多的功能。所以没有太大的区别,取决于你打算用它做什么。您可能更喜欢使用数组而不是 List - 直到您需要 List 提供的一些功能,而不是 List。
  • 这样的聚合数组声明是为了实例化静态数据数组而完成的,而列表意味着动态形式,并且比数组更可能是方法调用的参数。从一个转换到另一个就像在说“现在它是不变的,但我们希望在未来的发展中得到一个列表”。至少我是这么读的。将数据直接添加到 ArrayList 相当于将 ! important tags 放在 css 文件中的规则旁边。换句话说,有点粗糙,即使它有效。 ;)

标签: java string arraylist


【解决方案1】:

“正常”的方式是使用第三种形式:

List<String> weatherForecast = new ArrayList<>();
Collections.addAll(weatherForecast,
        "Mon 6/23 - Sunny - 31/17",
        "Tue 6/24 - Foggy - 21/8",
        "Wed 6/25 - Cloudy - 22/17",
        "Thurs 6/26 - Rainy - 18/11",
        "Fri 6/27 - Foggy - 21/10",
        "Sat 6/28 - TRAPPED IN WEATHERSTATION - 23/18",
        "Sun 6/29 - Sunny - 20/7");

List 是一个接口,使用它可以使用另一个实现类,如 LinkedList(仅用于几个元素)。也可用作参数类型。

这使用集合实用程序类来添加可变参数... 字符串。并在后台使用String[] 来表示这些参数。

第一个选项的.asList 足以让List&lt;String&gt; 不添加。

【讨论】:

  • @sᴜʀᴇsʜᴀᴛᴛᴀ 两种样式都可以在旧样式代码中找到,第一种较新,但更具间接性。第二个最直接,但过于冗长。
  • 这种方式没有问题,但我个人更喜欢OP的第一个示例中的数组转换。
【解决方案2】:

第一种方法:

  • 更好的可读性(可以更好,请参阅我的替代方案);所有数据都直接用逗号分隔,而不是通过方法调用来添加每个数据。
  • Arrays.asList 使用内部ArrayList 类为给定的特定数组创建一个 fixed-size 列表,该类只是数组本身的包装器,比创建数组的完整副本更高效.
  • 您将数据保存在 List 变量中,而不是 ArrayList 变量中,这为您提供了更大的灵活性。

第二种方法:

  • 您使用的是原始类型,一开始很糟糕。
  • 没有优势。

如果您使用这种方法,请至少以通用方式声明您的List

ArrayList<String> weatherForecast = new ArrayList<>();

替代方案:

请注意,您可以直接这样做:

List<String> weatherForecast = Arrays.asList(
    "Mon 6/23 - Sunny - 31/17",
    "Tue 6/24 - Foggy - 21/8",
    "Wed 6/25 - Cloudy - 22/17",
    "Thurs 6/26 - Rainy - 18/11",
    "Fri 6/27 - Foggy - 21/10",
    "Sat 6/28 - TRAPPED IN WEATHERSTATION - 23/18",
    "Sun 6/29 - Sunny - 20/7"
);

【讨论】:

  • 您先指定,最后将其用作替代方案。我很困惑:)
  • @sᴜʀᴇsʜᴀᴛᴛᴀ 我指定了它,但从未将其限定为优点/缺点;它只需要按原样使用。我假设如果讲师使用它,那么它是不可变的这一事实就没有问题。考虑到这一点,我给出了一个替代方案,它以一种更易读的方式做同样的事情。
【解决方案3】:

两者都做同样的事情。

但不同的是,第一个使它更具可读性。您会确切地知道您正在将天气预报信息添加到列表中。

在第二种情况下,您只需继续添加信息,使用add(),这实际上看起来比另一个笨拙。

假设您将素数添加到列表中

First Approach:
int [] primeNums = {2, 3, 5, 7, 11, 13, 17, 19};
List<Integer> primes = new ArrayList<>(Arrays.asList(primeNums));

Second Approach:
List<Integer> primes = new ArrayList<>();
primes.add(2);
primes.add(3);
primes.add(5);
primes.add(7);
primes.add(11);
primes.add(13);
primes.add(17);
primes.add(19);

您也可以遍历数组并添加它。

for(int i = 0; i < primeNums.length; ++i)
  primes.add(primeNums[i]);

【讨论】:

    【解决方案4】:

    在性能方面,您的答案可能会更好,因为您正在实例化一个唯一的数据结构 (ArrayList) 并向其中添加元素。除了可读性部分之外,您的讲师正在实例化两个数组,然后将其转换为一个可增长数组的 arrayList。它可能不会对性能造成太大影响,但您的性能肯定会更快。

    【讨论】:

    • 性能方面,当您复制所有数据时它会变慢,而第一个选项返回数组的包装器并且不复制它。
    【解决方案5】:

    两者都在做同样的事情;但代码可读性很重要;

    考虑一个例子--

    允许应用程序将值放入最大容量的数组中,并且作为per this link,最多可以在数组中允许Integer.MAX_VALUE - 5 值。 填充数组后,开发人员需要像上面那样将其转换为 List。

    现在,想想如果有人在这种情况下使用add 方法,那么代码行肯定会增加,代码将变得难以阅读。

    所以在这种情况下,首选操作是使用Arrays.asList(data)

    【讨论】:

      【解决方案6】:

      没有什么特别的优势。

      在第一种情况下,您不必要地将 Arrays.asList() 创建的数组包装为新数组。

      使用第二种情况,前提是数组内容是静态的。

      【讨论】:

      • 我会说“优势”是使用第一种方法你必须编写更少的代码......如果它可以称为“优势”
      • @BackSlash 在这种情况下对我来说似乎没有优势:)
      • 实际上 Arrays.asList 返回一个具有只读结构的列表。您无法从列表中添加或删除。 .此外,Arrays.asList 不返回 java.util.arraylist。它返回 java.util.arrays$arraylist。这很重要,因为实例检查可能会失败
      • @Nyerguds - 我同意 对接口进行编码 在 99% 的情况下是首选的。但在某些情况下,您可能会明确期望列表类型优于另一个出于性能原因。
      • @TheLostMind 正如我所说,我真的不喜欢“对接口进行编码”,因为大多数时候,所做的一切都是不必要地隐藏实际使用的实现的特定选项。这实际上是对变量声明为List&lt;String&gt; 的讽刺评论,而不是对ArrayList 构造函数的调用。
      猜你喜欢
      • 2023-03-21
      • 2013-02-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多