Java. Расширенный цикл for в стиле for each. Общая форма. Примеры. Обработка массивов, коллекций объектов ArrayList, LinkedList

Расширенный цикл for в стиле for each. Общая форма. Примеры. Обработка массивов, коллекций объектов ArrayList, LinkedList


Содержание


1. Назначение, общая форма и принцип работы расширенного цикла for

В программах на Java очень часто нужно реализовывать обработку массивов, коллекций, наборов данных. Наиболее распространенной операцией при обработке массивов данных есть перебор каждого элемента массива. Для обеспечения перебора используется один из известных операторов цикла (for, while, do…while). Наиболее часто для перебора элементов массива используется цикл for.

Поскольку, перебор элементов массива есть стандартной операцией, то разработчики Java ввели дополнительный формат цикла for, который обеспечивает более упрощенную, рациональную его реализацию. В этой реализации общая форма цикла for подобна к форме цикла foreach в других языках программирования.

Общая форма расширенного цикла for следующая:

for (type variable : collection) {
    // некоторые операторы
    // ...
}

где

  • type – тип внутренней переменной с именем variable;
  • variable – внутренняя переменная типа type, которая имеет видимость в границах блока фигурных скобок { }. Эта переменная есть итерационной, она сохраняет элементы набора данных collection;
  • collection – набор данных, которые по-очереди перебираются в цикле. Набором данных может служить коллекция или массив.

Расширенный цикл for работает следующим образом. В расширенном цикле for происходит последовательный перебор всех элементов коллекции или массива. Количество итераций цикла равна количеству элементов в коллекции или массиве. На каждой итерации значение элемента массива помещается в итерационную переменную variable, которую можно обрабатывать или использовать. Цикл гарантирует прохождение всей коллекции (массива) от первого элемента до последнего.

 

2. Примеры обработки массивов расширенным циклом for
2.1. Пример. Обработка массива чисел типа int (примитивный тип данных).

В примере демонстрируется использование расширенного цикла for для обработки одномерного целочисленного массива A. Реализован подсчет числа парных чисел массива.

// инициализация одномерного массива A
int[] A = { 1, 8, 3, 6, 5, 10, 31 , 24, 10, 13, 2, 4 };
int k = 0; // количество парных чисел

// расширенный цикл for
for (int d : A)
    if (d % 2 == 0)
        k++;
// k = 7

 


 

2.2. Пример. Обработка массива объектов типа Book (книга)

Пусть задан класс Book, реализующий книгу

// класс, реализующий книгу
class Book {
    String title; // название книги
    String author; // имя автора
    float price; // цена
    int year; // год издания
}

Использование расширенного цикла for для массива типа Book может быть, например, следующим:

// объявление одномерного массива типа Book
Book B[];

// выделить память для массива из 4 ссылок на тип Book
B = new Book[4];

// выделить память для каждого элемента массива типа Book
for (int i=0; i<B.length; i++)
    B[i] = new Book();

// заполнить массив значениями
B[0].title = "Book-1";
B[0].author = "Author-1";
B[0].price = 205.78f;
B[0].year = 2008;

B[1].title = "Book-2";
B[1].author = "Author-2";
B[1].price = 99.00f;
B[1].year = 2010;

B[2].title = "Book-3";
B[2].author = "Author-3";
B[2].price = 0.99f;
B[2].year = 2011;

B[3].title = "Book-4";
B[3].author = "Author-4";
B[3].price = 100.01f;
B[3].year = 2012;

// расширенный цикл for
// поиск книг 2011, 2012 годов
for (Book book : B)
    if ((book.year==2011)||(book.year==2012))
        System.out.println("Book: " + book.title + ", " + book.author);

В результате выполнения вышеприведенного кода будут выведены строки

Book: Book-3, Author-3
Book: Book-4, Author-4

 

3. Примеры обработки коллекций расширенным циклом for
3.1. Пример. Обработка коллекции типа Integer с помощью динамического массива ArrayList

В примере демонстрируется обработка коллекции целых чисел с помощью классов ArrayList и Integer.

Класс ArrayList реализует динамический массив, который может увеличиваться или уменьшаться по мере необходимости. Чтобы использовать данный класс нужно подключить пакет java.util. Объявление класса ArrayList следующее:

class ArrayList<E>

где

  • E – тип объектов, которые сохраняются в массиве.

Класс Integer есть классом-оберткой над типом int, который представляет целочисленные значения. В данном примере класс ArrayList для обработки объектов типа Integer имеет вид:

class ArrayList<Integer>

Демонстрация использования расширенного цикла for для коллекции целых чисел с помощью класса ArrayList может быть, например, такой

// подключить пакет java.util
import java.util.*;

...

// класс ArrayList, объект типа коллекция Integer
// Integer - класс-обертка для типа int
ArrayList<Integer> A = new ArrayList<Integer>(); // создать коллекцию

// добавить элементы в коллекцию
A.add(5);
A.add(9);
A.add(-20);
A.add(11);
A.add(7); // A = { 5, 9, -20, 11, 7 }

// найти сумму элементов коллекции
int sum = 0;
    for (Integer i : A) // расширенный цикл for
        sum += i;

System.out.println("Sum = " + sum); // Sum = 12

 

3.2. Обработка коллекции типа Book с помощью связного списка LinkedList

Пусть задан класс (тип) Book, который имеет следующее объявление:

// класс, который реализует книгу
class Book {
    String title; // название книги
    String author; // имя автора
    float price; // цена
    int year; // год издания
}

В данном примере для демонстрации расширенного цикла for используется класс LinkedList. Этот класс предназначен для организации данных заданного типа в связный список. Чтобы использовать класс LinkedList в программе нужно подключить пакет java.util. Объявление класса имеет вид:

class LinkedList<E>

где

  • E – тип объектов, которые сохраняются в списке. В нашем случае этим типом есть класс Book.

Программный код, который формирует список книг типа Book и обрабатывает его в расширенном цикле for (поиск заданной книги) имеет вид:

// подключить пакет java.util
import java.util.*;

...

// объявить и создать объект типа LinkedList<Book>
LinkedList<Book> LB = new LinkedList<Book>();
Book B = new Book(); // дополнительная переменная

// сформировать список объектов LinkedList<Book>

// сформировать объект типа Book
B.title = "Title-1";
B.author = "Author-1";
B.price = 10.00f;
B.year = 2000;

// добавить объект B в список
LB.add(B);

// добавить второй объект
B = new Book(); // выделить память 
B.title = "Title-2";
B.author = "Author-2";
B.price = 20.00f;
B.year = 2001;
LB.add(B);

// добавить третий объект
B = new Book(); // выделить память
B.title = "Title-3";
B.author = "Author-3";
B.price = 30.00f;
B.year = 2002;
LB.add(B);

// вывести список LB
int i=0;
    for (Book B2 : LB) {
        i++;
        System.out.println("Book - " + i + ": " + B2.title + ", " + B2.author);
    }

System.out.println("-----------------------------------");

// вывести книги 2001 года выпуска
for (Book B2 : LB)
    if (B2.year == 2001)
        System.out.println(B2.title + ", " + B2.author + ", " + B2.year);

В вышеприведенном коде в строках

int i=0;
for (Book B2 : LB) {
    i++;
    System.out.println("Book - " + i + ": " + B2.title + ", " + B2.author);
}

номер позиции в связном списке Book вычисляется путем введения дополнительной переменной i. Бывают случаи, когда нужно обрабатывать не все элементы коллекции. По значению итератора i можно определять номер позиции объекта коллекции, который может быть обработан.

После выполнения вышеприведенного кода на экран будет выведено:

Book - 1: Title-1, Author-1
Book - 2: Title-2, Author-2
Book - 3: Title-3, Author-3
-----------------------------------
Title-2, Author-2, 2001

 

4. Какие преимущества и недостатки применения расширенного цикла for для массивов

Расширенный цикл for есть удобным для обработки коллекций. Использование расширенного цикла for дает следующие преимущества:

  • упрощенность и рациональность представления в сравнении с циклом for;
  • не нужно использовать дополнительную переменную цикла, задавать ее начальное значение и условие завершения цикла;
  • не нужно индексировать массив.

Основной недостаток расширенного цикла for:

  • отсутствие «гибкости» в оперировании итерационной переменной в случаях, когда нужно осуществлять перебор не всех элементов коллекции. Например, если нужно перебирать только первые n элементов всей коллекции или элементы, которые лежат на определенных позициях (четных позициях, нечетных позициях) в коллекции. Однако, этот недостаток можно обойти введением дополнительных переменных-итераторов и проверки соответствующих условий.

 


Связанные темы