Рубрики
Без рубрики

Java для эволюции циклов

java для цикла, итератор java, java для каждого цикла, эволюция цикла for в java, вывод метода java, java для каждого примера потребителя, пример итератора списка java, методы итерации в java, java basic для цикла, java enhanced для цикла.

Автор оригинала: Pankaj Kumar.

Итерация является одним из самых основных требований в любом языке программирования, и, прежде всего, “для” является наиболее широко используемым циклом в java для итерации. Мы увидим эволюцию java для методов итерации циклов.

Java для эволюции циклов

Мы будем работать над примером отображения имен актеров из коллекции . Для простоты давайте возьмем список и настроим его:

List actors = Arrays.asList("Jack Nicholson", "Marlon Brando", "Robert De Niro", "Al Pacino", "Tom Hanks");

Давайте начнем рассматривать эволюцию цикла for в разных версиях java.

Базовый для цикла

Основными элементами цикла “для” являются инициализация, условие завершения и логика приращения цикла. Давайте посмотрим образец здесь:

for (int i = 0; i < actors.size(); i++) {
  System.out.println(actors.get(i));
} 

Если мы хотим выполнить итерацию по коллекции, которая не относится к типу List, у нас не будет метода get(int index) , который даст нам индексированное значение из коллекции. Следовательно, в Java 1.2 Были введены итераторы . Давайте посмотрим, как мы решаем ту же проблему с итераторами:

for (Iterator iterator = actors.iterator(); iterator.hasNext();) {
 System.out.println(iterator.next());
}

для каждого (Улучшено для цикла)

Этот цикл был введен в Java 5, он устраняет беспорядок, церемонию и возможность ошибки, полностью скрывая итератор или переменную индекса. Давайте посмотрим на это в действии:

for (String actor : actors) {
 System.out.println(actor);
}

Приведенные выше примеры относятся к типам внешних итераторов, здесь логика управления и завершения находится во внешнем итераторе. Это может привести к общей сложности и может привести к ошибкам.

Внутренний цикл forEach

В Java 8 , с внедрением функционального интерфейса и лямбды , архитекторы Java предоставили нам внутренний итератор (цикл forEach), поддерживаемый платформой Collection, и его можно использовать с объектом collections. Этот метод выполняет заданное действие для каждого элемента коллекции. Давайте рассмотрим это более подробно:

Подпись метода : публичная недействительность для каждого(действие потребителя)

Для каждого используется реализация Потребитель (Функциональный интерфейс), которая имеет прием(T t) метод для выполнения логики внутри цикла. Давайте посмотрим на реализацию:

actors.forEach(new Consumer() {
	public void accept(String actor) {
		System.out.println(actor);
	}
});

Здесь методу forEach присваивается анонимный внутренний класс пользовательского интерфейса . Этот класс имеет метод accept(T t) , который вызывается для всех значений коллекции. Этот код страдает недостатком дизайна, когда каждый раз при использовании forEach создается новый класс в обход анонимного внутреннего класса.

ForLoopEvolution$1.class
ForLoopEvolution.class

Это решение выглядит более подробным и сложным, чем предыдущие циклы. Давайте попробуем переработать это упрощенным способом. Вся реализация функционального интерфейса может быть написана в виде лямбда-функции, что более интуитивно понятно. Давайте посмотрим на это в действии:

actors.forEach((e) -> {
 System.out.println(e);
 });

Для каждого элемента e актер отображается в консоли. Этот код можно упростить еще больше, удалив ненужные фигурные скобки и скобки.

actors.forEach(e -> System.out.println(e));

Основное преимущество использования лямбда-кода вместо анонимного внутреннего класса заключается в том, что нет загрязнения байт-кода, нет создания класса, вместо этого вызов лямбда-кода откладывается до времени выполнения. Давайте посмотрим байт-код для получения более подробной информации:

invokedynamic помогает JVM создать байт-код из лямбда-выражения и отложить выполнение до времени выполнения.

Вывод метода

Вывод метода дополнительно устраняет некоторые дополнительные церемонии и многословие. Давайте проведем рефакторинг, чтобы передать вывод метода вместо лямбда:

actors.forEach(System.out::println);

Одним из дополнительных преимуществ использования внутреннего итератора является то, что код почти готов к параллелизму. В Java 8 с внедрением потокового api мы можем запускать код параллельно без необходимости синхронизации. Из коллекции можно создать параллельный поток для обработки нашей функциональности.

actors.parallelStream().forEach(System.out::println);

Резюме

Внутренние итераторы менее сложны и менее подвержены ошибкам, их лучше обслуживать. Код с использованием внутреннего итератора можно легко сделать параллельным.

Ссылка на код : URL-адрес GitHub для Java-кода