Есть функция foo, которая возвращает массив bar. Будет ли одинакова последовательность работы у цикла foreach, если в качестве иттерируемого объекта передать foo и bar? Будет ли вызваться функция foo каждый раз или условно закешируется?
Работать будет одинаково. При вызове for (Object a : foo()) {} у вас сначала один раз вызовется метод, по результату которого пойдёт итерирование.
foreach - всего лишь "синтаксический сахар" для создания итератора и дальнейшего его использования. Т.е. "под капотом" это:
Iterator it = foo().iterator();
while(it.hasNext()) {
it.next();
}
В Java нет цикла foreach, есть for, за исключением stream api - где действительно есть метод forEach.
Но это немного другое.
Если поместить функцию, которая не кеширует результат в переменной или объекте, она будет вызываться при каждой итерации.
final String str = "text;
Плохой цикл:
for (int i = 0; i < str.length(); ++i) {
// .......
}
Хороший цикл:
for (int i = 0, max = str.length(); i < max; ++i) {
// .......
}
Сборка персонального компьютера от Artline: умный выбор для современных пользователей