Использование ArrayList вместо массива, чтобы избежать использования нормального цикла for

1

Я просматриваю фрагмент кода, который выглядит так:

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

Список создается таким образом, что можно использовать расширенный цикл цикла, а затем он преобразуется в возвращаемый массив.

Будет ли это лучше с точки зрения производительности и стиля кода?

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;
}
  • 2
    Возможно, вы не поймете, что расширенный цикл for прекрасно работает и с массивами.
  • 0
    Нет, он заметил, но меня больше беспокоит, что это пример кода (поскольку item не wrappedItems когда помещается в wrappedItems ). Это для переполнения стека.
Показать ещё 6 комментариев
Теги:
arrays
loops

3 ответа

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

С точки зрения стиля кода с использованием расширенного цикла увеличивается читаемость, поскольку она более абстрактна, чем "стандартная" для цикла.

Стандарт для увеличения контроля, но вводит также пространство для возможных ошибок, так как вы манипулируете индексами и длинами, с которыми все знакомы, но все же он раскрывает некоторые внутренние структуры данных, которые каким-то образом против инкапсуляции...

Посмотрите также на этот пост. Каковы преимущества Enhanced for loop и Iterator в Java?

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 создает некоторые накладные расходы, но в большинстве практических сценариев она будет незначительной. Как указывалось другими, вы также можете комбинировать цикл для каждого цикла с дополнительной индексной переменной, но для меня он не выглядит убедительным, поскольку индексная переменная имеет неправильную область действия (вы должны объявить ее за пределами цикла) и ее не намного проще, чем традиционный для цикла.

Возможно, последние слова взяты из решения 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);
}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню