
- •Введение
- •1 Концепции объектно-ориентированного программирования
- •1.1 Классы и объекты
- •1.2 Геттеры и сеттеры
- •1.3 Перегрузка методов
- •1.4 Ключевые слова this и super
- •1.5 Метод toString()
- •1.6 Конструкторы
- •1.7 Определение класса в Java
- •1.8 Принципы ООП
- •1.8.1 Абстракция
- •1.8.2 Инкапсуляция
- •1.8.3 Наследование
- •1.8.4 Полиморфизм
- •1.9 Переопределение методов
- •1.10 Подстановка
- •1.11 Апкастинг и даункастинг
- •1.13 Абстрактные классы и интерфейсы
- •1.13.1 Абстрактные классы
- •1.13.2 Интерфейсы
- •2 Типы отношений между классами и объектами
- •2.1 Ассоциация
- •2.2 Агрегация
- •2.3 Композиция
- •2.4 Наследование
- •3 Введение во фреймворк «Коллекции». Обобщения
- •3.1 Коллекции
- •3.2 Перебор элементов коллекций
- •3.3 Обобщения
- •3.3.2 Дженерик-методы и универсальные конструкторы
- •3.3.3 Подстановочные символы (wildcard)
- •4 Потоки ввода-вывода и потоки выполнения. Многопоточное программирование
- •4.1 Потоки
- •InputStream
- •OutputStream
- •Символьные потоки
- •Специализированные потоки
- •Файловые потоки
- •Стандартные потоки ввода-вывода
- •Чтение из стандартного ввода
- •Ввод с консоли
- •Форматированный вывод
- •Класс File
- •Методы класса File
- •4.2 Сериализация и десериализация объектов
- •4.2.1 Сериализация
- •4.2.2 Десериализация
- •4.2.3 Исключение данных из сериализации
- •4.2.4 Сериализация статических полей
- •4.2.5 Сериализация с массивом или коллекцией
- •4.2.6 Сериализация Java с наследованием
- •4.2.7 Сериализация Java с агрегированием
- •4.2.8 SerialVersionUID
- •4.3 Потоки выполнения
- •4.4. Жизненный цикл потока
- •4.5 Многопоточность
- •4.5.1 Главный поток
- •4.5.2 Создание и завершение потоков
- •4.5.3 Завершение потока
- •4.5.4 Управление приоритетами
- •4.5.5 Синхронизация потоков
- •4.5.6 Состояния потока
- •4.5.7 Блокировка
- •5 Лямбда-выражения
- •Заключение
- •Литература
- •Глоссарий
|
60 |
|
|
Map |
size() – возвращает количество элементов |
|
containsKey(Object key) – проверяет наличие ключа |
|
containsValue(Object value) – проверяет наличие значения в ас- |
|
социативном массиве |
|
get(Object key) – возвращает значение по ключу |
|
put(K key, V value) – кладет в ассоциативный массив значение |
|
value по ключу key. В случае наличия уже такого ключа происходит |
|
замена значения |
|
values() – возвращает значения всех элементов в виде коллекции |
|
|
|
remove(Object key) – удаляет элемент с ключом key, возвращая |
|
значение этого элемента (вернет null в случае отсутствия) |
|
|
|
clear() – удаляет все элементы из массива |
|
isEmpty() – возвращает, не пуст ли массив |
|
containsKey(Object key) – проверяет наличие ключа |
|
|
3.2Перебор элементов коллекций
1.Перебор с помощью итератора.
Интерфейс Collection расширяет интерфейс Iterable, у которого есть только один метод iterator(). Объект типа Iterator может использоваться для последовательного перебора элементов коллекции.
Интерфейс Iterator имеет следующее определение:
public interface Iterator <E> { E next();
boolean hasNext(); void remove();
}
Реализация интерфейса предполагает, что с помощью вызова метода next() можно получить следующий элемент. С помощью метода hasNext() можно узнать, есть ли следующий элемент и не достигнут ли конец коллекции. И если элементы еще имеются, то hasNext() вернет значение true. Метод hasNext() следует вызывать перед методом next(), так как при достижении конца коллекции метод next() выбрасывает исключение NoSuchElementException и метод remove() удаляет текущий элемент, который был получен последним вызовом next().
Используем итератор для перебора коллекции ArrayList. Создадим список студентов students.
import java.util.*;
ArrayList<Student> students = new ArrayList<Student>();

61
students.add(new students.add(new students.add(new
Student("Иванов Иван Иванович")); Student("Петров Петр Петрович")); Student("Сидоров Сергей Сергеевич"));
Iterator<Student> iter = students.iterator(); while(iter.hasNext()) {
System.out.println(iter.next().getFIO());
}
В результате итератор переберет все элементы коллекции, пока не пусто. Одновременно с методом next() вызвали getFIO(), чтобы получать только Ф.И.О. (рис. 3.3). Если просто использовать students.next(), то получим результат вывода метода toString(), переопределенного в классе Student.
Рис. 3.3 – Вывод элементов коллекции
Интерфейс Iterator предоставляет ограниченный функционал. Гораздо больший набор методов предоставляет другой итератор – интерфейс ListIterator. Данный итератор используется классами, реализующими интерфейс
List, то есть классами LinkedList, ArrayList и др.
Интерфейс ListIterator расширяет интерфейс Iterator и определяет ряд дополнительных методов:
void add(E obj): вставляет объект obj перед элементом, который должен быть возвращен следующим вызовом next();
boolean hasNext(): возвращает true, если в коллекции имеется следующий элемент, иначе возвращает false;
boolean hasPrevious(): возвращает true, если в коллекции имеется предыдущий элемент, иначе возвращает false;
E next(): возвращает следующий элемент; если такого нет, то гене-
рируется исключение NoSuchElementException;
E previous(): возвращает предыдущий элемент; если такого нет, то генерируется исключение NoSuchElementException;

62
int nextIndex(): возвращает индекс следующего элемента; если такого нет, то возвращается размер списка;
int previousIndex(): возвращает индекс предыдущего элемента; если такого нет, то возвращается число –1;
void remove(): удаляет текущий элемент из списка. Таким образом, этот метод должен быть вызван после методов next() или previous(), иначе будет сгенерировано исключение IlligalStateException;
void set(E obj): присваивает текущему элементу, выбранному
вызовом методов next() или previous(), ссылку на объект obj. Добавим в наш пример новый итератор ListIterator.
ListIterator<Student> listIter = students.listIterator();
while(listIter.hasNext()) { System.out.println(listIter.next().getFIO());
}
//сейчас текущий элемент – Сидоров Сергей Сергеевич
//изменим значение этого элемента
listIter.set(new Student("Васильев Василий Петрович")); // пройдемся по элементам в обратном порядке //новый список
System.out.println("новый список"); while(listIter.hasPrevious()) { System.out.println(listIter.previous().getFIO());
}
В результате итератор переберет все элементы коллекции, пока не пусто. Затем пройдется по элементам в обратном порядке. Получится два списка
(рис. 3.4).
Рис. 3.4 – Вывод элементов коллекции с помощью итератора ListIterator
2. Перебор с помощью цикла forEach.
63
В Java 8 у интерфейса Iterable появился метод forEach, принимающий лямбда-выражение и применяющий это выражение на каждый элемент коллекции:
students.forEach(n -> System. out.println(n.getFIO()));
3. Перебор с помощью расширенного цикла for.
for(Student n: students) { System.out.println(n.getFIO());
}
Также для перебора можно использовать простые конструкции циклов. Рассмотрим пример перебора на примере очереди (Queue), у которой есть
дополнительные методы по добавлению, извлечению и проверке элементов. Чаще всего порядок выдачи элементов соответствует FIFO (firstin, first-out), но в общем случае определяется конкретной реализацией. Очереди не могут хранить null. У очереди может быть ограничен размер.
Основные методы очереди:
element(); – возвращает, но не удаляет головной элемент очереди;
offer(E o); – добавляет в конец очереди новый элемент и возвращает true, если вставка удалась;
peek(); – возвращает первый элемент очереди, не удаляя его;
poll(); – возвращает первый элемент и удаляет его из очереди;
remove(); – возвращает и удаляет головной элемент очереди.
Queue<Student> queue = new LinkedList<Student>(); queue.offer(new Student("Иванов Иван Иванович")); queue.offer(new Student("Петров Петр Петрович")); queue.offer(new Student("Сидоров Сергей Сергеевич")); queue.offer(new Student("Васильев Василий Петрович"));
for (Student str : queue) { System.out.println(str.getFIO());
}
System.out.println("head:"+queue.peek().getFIO()); //возвращает, но не удаляет первый элемент очереди
Результат на консоли представлен на рисунке 3.5.

64
Рис. 3.5 – Вывод элементов коллекции Queue
Интерфейс Deque позволяет реализовать двунаправленная очередь, разрешающая вставку и удаление элементов в два конца очереди.
Методы addFirst(e), addLast(e) вставляют элементы в начало и в конец очереди соответственно. Метод add(e) унаследован от интерфейса Queue и абсолютно аналогичен методу addLast(e) интерфейса Deque.
Deque<Student> deque = new LinkedList<Student>(); deque.offer(new Student("Иванов Иван Иванович")); deque.offer(new Student("Петров Петр Петрович"));
deque.addFirst(new Student("Сидоров Сергей Петрович")); //головной элемент
deque.offer(new Student("Васильев Василий Петрович")); for (Student str : deque) {
System.out.println(str.getFIO());
}
System.out.println("head:"+deque.peek().getFIO()); //возвращает, но не удаляет первый элемент очереди
Результат на консоли представлен на рисунке 3.6.
Рис. 3.6 – Вывод элементов коллекции Deque
Сортировку и сравнение коллекций рассмотрим в главе о лямбда-выраже-
ниях. |
|
· · · · · · · · · · · · · · · · · · · · · · · · · |
Выводы · · · · · · · · · · · · · · · · · · · · · · · · · |
Главные преимущества коллекций: