Я просматриваю фрагмент кода, который выглядит так:
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;
}
Нет причин, по которым вы не можете просто напрямую построить массив и использовать расширенный цикл 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;
}
С точки зрения стиля кода с использованием расширенного цикла увеличивается читаемость, поскольку она более абстрактна, чем "стандартная" для цикла.
Стандарт для увеличения контроля, но вводит также пространство для возможных ошибок, так как вы манипулируете индексами и длинами, с которыми все знакомы, но все же он раскрывает некоторые внутренние структуры данных, которые каким-то образом против инкапсуляции...
Посмотрите также на этот пост. Каковы преимущества Enhanced for loop и Iterator в Java?
Поскольку ваш код написан в вопросе, вы не обертываете элемент (несмотря на имя), а просто помещаете в другой тип массива. Это можно сделать еще проще:
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);
}
item
неwrappedItems
когда помещается вwrappedItems
). Это для переполнения стека.