使用ArrayList而不是数组来避免使用普通的for循环

时间:2014-07-30 15:03:17

标签: java arrays loops

我正在审核一段看起来像这样的代码:

public WrappedItem[] processItems(Item[] items)
{
    List<WrappedItem> wrappedItems = new ArrayList<>();   
    for (Item item : items)
    {
        /* …do something with the item… */
        wrappedItems.add(WrappedItem.wrap(item));
    }
    return wrappedItems.toArray(new WrappedItem[0]);
}

创建一个列表,以便可以使用增强的for循环,然后将其转换为要返回的数组。

从性能和代码风格的角度来看,这会更好吗?

public WrappedItem[] processItems(Item[] items)
{
    WrappedItem[] wrappedItems = WrappedItem[items.length];   
    for (int i = 0; i < items.length; i++)
    {
        Item item = items[i]
        /* …do something with the item… */
        wrappedItems[i] = WrappedItem.wrap(item);
    }
    return wrappedItems;
}

3 个答案:

答案 0 :(得分:2)

没有理由你不能简单地直接构造数组使用高级for循环:

public WrappedItem[] processItems(Item[] items)
{
    WrappedItem[] wrappedItems = WrappedItem[items.length];
    int i = 0;
    for (Item item : items)
    {
        /* …do something with the item… */
        wrappedItems[i++] = item;
    }
    return wrappedItems;
}

答案 1 :(得分:0)

从代码风格的角度来看,使用增强型循环增加了可读性,因为它比#34;标准&#34;更抽象。 for循环。

增加控制的标准,但也引入了可能出错的空间,因为您正在操纵每个人都熟悉的索引和长度,但它仍然暴露了一些内部数据&#39 ; s结构以某种方式反对封装...

还要看一下这篇文章What are the Advantages of Enhanced for loop and Iterator in Java?

答案 2 :(得分:0)

由于您的代码是在问题中编写的,所以您没有包装项目(尽管名称),而只是放入一个不同类型的数组。这可以更容易地完成:

public WrappedItem[] processItems(Item[] items)
{
  WrappedItem[] wrappedItems
    = Arrays.copyOf(items, items.length, WrappedItem[].class);
  for (Item item : items)
  {
    /* …do something with the item… */
  }
  return wrappedItems;
}

如果您需要兼容Java 5,可以使用

WrappedItem[] wrappedItems = Arrays.asList(items).toArray(new WrappedItem[0]);

而不是Arrays.copyOf


现在你已经更新了你的问题,很明显它并不那么容易。然后答案是基于List的版本会产生一些开销,但在大多数实际情况下它可以忽略不计。正如其他人所指出的那样,你也可以将for-each循环与一个额外的索引变量结合起来,但对我来说它看起来并不令人信服,因为索引变量的范围是错误的(你必须在循环之外声明它)并且它不是真的比传统的for循环简单。

也许最后的话来自Java 8解决方案:

public WrappedItem[] processItems(Item[] items) {
  return Arrays.stream(items)
      .map(item -> {
          /* …do something with the item… */
          return WrappedItem.wrap(item);
      }).toArray(WrappedItem[]::new);
}

public WrappedItem[] processItems(Item[] items) {
  return Arrays.stream(items)
      .peek(item -> {
          /* …do something with the item… */
      }).map(WrappedItem::wrap).toArray(WrappedItem[]::new);
}