Цикл for-each, представленный в версии 1.5, устраняет помехи и возможность ошибки, полностью скрывая итератор или индексную переменную. Полученная идиома в равной степени применима к коллекциям и массивам.:
// The preferred idiom for iterating over collections and arrays for (Element e : elements) { doSomething(e); }
Когда вы видите двоеточие (:), считайте его как “в”. Таким образом, приведенный выше цикл читается как “для каждого элемента e в elements”. Обратите внимание что нет снижения производительности при использовании цикла for-each даже для массивов. Фактически, это может предложить небольшое преимущество в производительности по сравнению с обычным циклом при некоторых обстоятельствах цикл for, поскольку он вычисляет предел индекса массива только один раз. А сделать это можно силы (пункт 45), программисты не всегда так делаю.
Ответ 2
Все эти циклы выполняют одно и то же, я просто хочу показать их, прежде чем вкладывать свои два цента.
Во -первых, классический способ перебора списка:
for (int i=0; i < strings.size(); i++) { /* do something using strings.get(i) */ }
Во-вторых, предпочтительный способ, поскольку он менее подвержен ошибкам (сколько раз ВЫ делали "ой, перепутали переменные i и j в этих циклах внутри циклов"?).
for (String s : strings) { /* do something using s */ }
В-третьих, микрооптимизированный цикл for:
intsize= strings.size(); for (inti= -1; ++i < size;) { /* do something using strings.get(i) */ }
Теперь собственно два цента: по крайней мере, когда я тестировал их, третий был самым быстрым при подсчете миллисекунд на то, сколько времени потребовалось для каждого типа цикла с простой операцией в нем, повторяющейся несколько миллионов раз - это использовало Java 5 с jre1.6u10 в Windows, на случай, если кому-то интересно.
Хотя, по крайней мере, кажется, что третий цикл самый быстрый, вам действительно следует спросить себя, хотите ли вы рискнуть внедрить эту оптимизацию "глазка" повсюду в своем циклическом коде, поскольку, судя по тому, что я видел, фактический цикл обычно не является самой трудоемкой частью любой реальной программы (или, может быть, я просто работаю не в том поле, кто знает). А также, как я упоминал в предлоге для Java для каждого цикла (некоторые называют это циклом итератора, а другие - циклом for-in), у вас меньше шансов столкнуться с этой конкретной глупой ошибкой при его использовании. И прежде чем обсуждать, как это вообще может быть быстрее других, помните, что javac вообще не оптимизирует байт-код (ну, почти вообще, во всяком случае), он просто компилирует его.
Однако, если вы занимаетесь микрооптимизацией и / или ваше программное обеспечение использует множество рекурсивных циклов и тому подобное, вас может заинтересовать третий тип цикла. Просто не забудьте тщательно протестировать свое программное обеспечение как до, так и после замены имеющихся у вас циклов for на этот странный, микрооптимизированный цикл.
Ответ 3
Что ж, влияние на производительность в основном незначительно, но не равно нулю. Если вы посмотрите на JavaDoc из RandomAccess интерфейса:
Как эмпирическое правило, реализация списка должна реализовывать этот интерфейс, если для типичных экземпляров класса этот цикл:
for (int i=0, n=list.size(); i < n; i++) list.get(i);
работает быстрее, чем этот цикл:
for (Iterator i=list.iterator(); i.hasNext();) i.next();
И цикл for-each использует версию с итератором, поэтому, например, цикл for ArrayList для каждого цикла не самый быстрый.
Ответ 4
Обычно следует отдавать предпочтение циклу for-each. Подход "get" может быть медленнее, если используемая вами реализация списка не поддерживает произвольный доступ. Например, если используется LinkedList , вы понесете затраты на обход, тогда как подход for-each использует итератор, который отслеживает его позицию в списке. Подробнее о нюансах цикла for-each.