ЦЕЛЬ ЛАБОРАТОРНОЙ РАБОТЫ:
Целью данной лабораторной работы является изучение работы с различными коллекциями в Java.
ТЕОРЕТИЧЕСКИЕ СВЕДЕНИЯ:
Коллекции.
Для хранения наборов данных в Java предназначены массивы. Однако их не всегда удобно использовать, прежде всего потому, что они имеют фиксированную длину. Эту проблему в Java решают коллекции. Однако суть не только в гибких по размеру наборах объектов, но в и том, что классы коллекций реализуют различные алгоритмы и структуры данных, например, такие как стек, очередь, дерево и ряд других.
Классы коллекций располагаются в пакете java.util, поэтому перед применением коллекций следует подключить данный пакет.
Хотя в Java существует множество коллекций, но все они образуют стройную и логичную систему. Во-первых, в основе всех коллекций лежит применение того или иного интерфейса, который определяет базовый функционал. Среди этих интерфейсов можно выделить следующие:
· Collection: базовый интерфейс для всех коллекций и других интерфейсов коллекций
· Queue: наследует интерфейс Collection и представляет функционал для структур данных в виде очереди
· Deque: наследует интерфейс Queue и представляет функционал для двунаправленных очередей
· List: наследует интерфейс Collection и представляет функциональность простых списков
· Set: также расширяет интерфейс Collection и используется для хранения множеств уникальных объектов
· SortedSet: расширяет интерфейс Set для создания сортированных коллекций
· NavigableSet: расширяет интерфейс SortedSet для создания коллекций, в которых можно осуществлять поиск по соответствию
· Map: предназначен для созданий структур данных в виде словаря, где каждый элемент имеет определенный ключ и значение. В отличие от других интерфейсов коллекций не наследуется от интерфейса Collection
Эти интерфейсы частично реализуются абстрактными классами:
· AbstractCollection: базовый абстрактный класс для других коллекций, который применяет интерфейс Collection
· AbstractList: расширяет класс AbstractCollection и применяет интерфейс List, предназначен для создания коллекций в виде списков
· AbstractSet: расширяет класс AbstractCollection и применяет интерфейс Set для создания коллекций в виде множеств
· AbstractQueue: расширяет класс AbstractCollection и применяет интерфейс Queue, предназначен для создания коллекций в виде очередей и стеков
· AbstractMap: также расширяет класс AbstractCollection и применяет интерфейс Map, предназначен для создания наборов по типу словаря с объектами в виде пары "ключ-значение"
· AbstractSequentialList: также расширяет класс AbstractList и реализует интерфейс List. Используется для создания связанных списков
С помощью применения вышеописанных интерфейсов и абстрактных классов в Java реализуется широкая палитра классов коллекций - списки, множества, очереди, отображения и другие, среди которых можно выделить следующие:
· ArrayList: простой список объектов
· LinkedList: представляет связанный список
· ArrayDeque: класс двунаправленной очереди, в которой мы можем произвести вставку и удаление как в начале коллекции, так и в ее конце
· HashSet: набор объектов или хеш-множество, где каждый элемент имеет ключ - уникальный хеш-код
· TreeSet: набор отсортированных объектов в виде дерева
· LinkedHashSet: связанное хеш-множество
· PriorityQueue: очередь приоритетов
· HashMap: структура данных в виде словаря, в котором каждый объект имеет уникальный ключ и некоторое значение
· TreeMap
Класс ArrayList.
Класс ArrayList представляет обобщенную коллекцию, которая наследует свою функциональность от класса AbstractList и применяет интерфейс List. Проще говоря, ArrayList представляет простой список, аналогичный массиву, за тем исключением, что количество элементов в нем не фиксировано.
ArrayList имеет следующие конструкторы:
· ArrayList(): создаетпустой список
· ArrayList(Collection<? extendsE>col): создает список, в который добавляются все элементы коллекции col.
· ArrayList (intcapacity): создает список, который имеет начальную емкость capacity
Емкость в ArrayList представляет размер массива, который будет использоваться для хранения объектов. При добавлении элементов фактически происходит перераспределение памяти - создание нового массива и копирование в него элементов из старого массива. Изначальное задание емкости ArrayList позволяет снизить подобные перераспределения памяти, тем самым повышая производительность.
Некоторые основные методы интерфейса List, которые часто используются в ArrayList:
· voidadd (intindex, Eobj): добавляет в список по индексу index объект obj
· booleanaddAll (intindex, Collection <? extendsE > col): добавляет в список по индексу index все элементы коллекции col. Если в результате добавления список был изменен, то возвращается true, иначе возвращается false
· Eget (intindex): возвращает объект из списка по индексу index
· intindexOf (Objectobj): возвращает индекс первого вхождения объекта obj в список. Если объект не найден, то возвращается -1
· intlastIndexOf (Objectobj): возвращает индекс последнего вхождения объекта obj в список. Если объект не найден, то возвращается -1
· Eremove (intindex): удаляет объект из списка по индексу index, возвращая при этом удаленный объект
· Eset (intindex, Eobj): присваивает значение объекта obj элементу, который находится по индексу index
· void sort(Comparator<? super E> comp): сортирует список с помощью компаратора comp
· List < E > subList (intstart, intend): получает набор элементов, которые находятся в списке между индексами start и end
Используем класс ArrayList и некоторые его методы в программе:
| import java.util.ArrayList; public class CollectionApp { public static void main(String[] args) { ArrayList<String> states = new ArrayList<String>(); // добавим в список ряд элементов states.add("Германия"); states.add("Франция"); states.add("Великобритания"); states.add("Испания"); states.add(1, "Италия"); // добавляем элемент по индексу 1 System.out.println(states.get(1));// получаем 2-й объект states.set(1, "Дания"); // установка нового значения для 2-го объекта System.out.printf("В списке %d элементов \n", states.size()); for(String state: states){ System.out.println(state); } if(states.contains("Германия")){ System.out.println("СписоксодержитгосударствоГермания"); } // удалим несколько объектов states.remove("Германия"); states.remove(0); Object[] countries = states.toArray(); for(Object country: countries){ System.out.println(country); } } } |
Здесь объект ArrayList типизируется классом String, поэтому список будет хранить только строки. Поскольку класс ArrayList применяет интерфейс Collection<E>, то мы можем использовать методы данного интерфейса для управления объектами в списке.
Для добавления вызывается метод add. С его помощью мы можем добавлять объект в конец списка: states.add("Германия"). Также мы можем добавить объект на определенное место в списке, например, добавим объект на второе место (то есть по индексу 1, так как нумерация начинается с нуля): states.add(1, "Италия")
Метод size() позволяет узнать количество объектов в коллекции.
Проверку на наличие элемента в коллекции производится с помощью метода contains. А удаление с помощью метода remove. И так же, как и с добавлением, мы можем удалить либо конкретный элемент states.remove("Германия");, либо элемент по индексуstates.remove(0); - удаление первого элемента.
Получить определенный элемент по индексу мы можем с помощью метода get(): Stringstate = states.get(1);, а установить элемент по индексу с помощью метода set: states.set(1, "Дания");
С помощью метода toArray() мы можем преобразовать список в массив объектов.
И поскольку класс ArrayList реализует интерфейс Iterable, то мы можем пробежаться по списку в цикле аляfor-each: for(Stringstate: states).
Хотя мы можем свободно добавлять в объект ArrayListдополнительные объекты, в отличие от массива, однако в реальности ArrayList использует для хранения объектов опять же массив. По умолчанию данный массив предназначен для 10 объектов. Если в процессе программы добавляется гораздо больше, то создается новый массив, который может вместить в себя все количество. Подобные перераспределения памяти уменьшают производительность. Поэтому если мы точно знаем, что у нас список не будет содержать больше определенного количества элементов, например, 25, то мы можем сразу же явным образом установить это количество, либо в конструкторе: ArrayList<String>states = newArrayList<String>(25);, либо с помощью метода ensureCapacity: states.ensureCapacity(25);
Класс LinkedList.
Обобщенный класс LinkedList<E> представляет структуру данных в виде связанного списка. Он наследуется от класса AbstractSequentialList и реализует интерфейсы List, Dequeue и Queue.
Класс LinkedList имеет следующие конструкторы:
· LinkedList(): создает пустой список
· LinkedList(Collection<? extends E>col): создает список, в который добавляет все элементы коллекции col
LinkedList содержит ряд методов для управления элементами, среди которых можно выделить следующие:
· addFirst() / offerFirst(): добавляет элемент в начало списка
· addLast() / offerLast(): добавляет элемент в конец списка
· removeFirst() / pollFirst(): удаляет первый элемент из начала списка
· removeLast() / pollLast(): удаляет последний элемент из конца списка
· getFirst() / peekFirst(): получает первый элемент
· getLast() / peekLast(): получает последний элемент
Рассмотрим применение связанного списка:
| packagecollectionapp; import java.util.LinkedList; public class CollectionApp { public static void main(String[] args) { LinkedList<String> states = new LinkedList<String>(); // добавим в список ряд элементов states.add("Германия"); states.add("Франция"); states.addLast("Великобритания"); // добавляем на последнее место states.addFirst("Испания"); // добавляем на первое место states.add(1, "Италия"); // добавляем элемент по индексу 1 System.out.printf("В списке %d элементов \n", states.size()); System.out.println(states.get(1)); states.set(1, "Дания"); for(String state: states){ System.out.println(state); } // проверка на наличие элемента в списке if(states.contains("Германия")){ System.out.println("Список содержит государство Германия"); } states.remove("Германия"); states.removeFirst(); // удаление первого элемента states.removeLast(); // удаление последнего элемента LinkedList<Person> people = new LinkedList<Person>(); people.add(new Person("Mike")); people.addFirst(new Person("Tom")); people.addLast(new Person("Nick")); people.remove(1); // удаление второго элемента for(Person p: people){ System.out.println(p.getName()); } Person first = people.getFirst(); System.out.println(first.getName()); // вывод первого элемента } } class Person{ private String name; public Person(String value){ name=value; } String getName(){return name;} } |
Здесь создаются и используются два списка: для строк и для объектов класса Person. При этом в дополнение к методам addFirst/removeLast и т.д., нам также доступны стандартные методы, определенные в интерфейсе Collection: add(), remove, contains, size и другие. Поэтому мы можем использовать разные методы для одного и того же действия. Например, добавление в самое начало списка можно сделать так: states.addFirst("Испания");, а можно сделать так: states.add(0, "Испания");
ВАРИАНТЫ ЗАДАНИЙ
1. Протестировать работу коллекции ArrayList.
2.Протестировать работу коллекции LinkedList.
3. Создать свою коллекцию, такую же как и ArrayList.
ЛАБОРАТОРНАЯ РАБОТА №8
РАБОТА С ФАЙЛАМИ
ЦЕЛЬ ЛАБОРАТОРНОЙ РАБОТЫ:
Освоить на практике работу с файлами на языке Java. Получить практические навыки по чтению и записи данных в файл.
ТЕОРЕТИЧЕСКИЕ СВЕДЕНИЯ:
Запись файлов. Класс FileWriter
Класс FileWriter является производным от класса Writer. Он используется для записи текстовых файлов.
Чтобы создать объект FileWriter, можно использовать один из следующих конструкторов:
| FileWriter(File file) FileWriter(File file, boolean append) FileWriter(FileDescriptorfd) FileWriter(String fileName) FileWriter(String fileName, boolean append) |
Так, в конструктор передается либо путь к файлу в виде строки, либо объект File, который ссылается на конкретный текстовый файл. Параметр append указывает, должны ли данные дозаписываться в конец файла (если параметр равен true), либо файл должен перезаписываться.
Запишем в файл какой-нибудь текст:
| import java.io.*; public class FilesApp { public static void main(String[] args) { try(FileWriter writer = new FileWriter("C:\\SomeDir\\notes3.txt", false)) { // запись всей строки Stringtext = "Мама мыла раму, раму мыла мама"; writer.write(text); // запись по символам writer.append('\n'); writer.append('E'); writer.flush(); } catch(IOException ex){ System.out.println(ex.getMessage()); } } } |
В конструкторе использовался параметр append со значением false - то есть файл будет перезаписываться. Затем с помощью методов, определенных в базовом классе Writer производится запись данных.
Чтение файлов. Класс FileReader
Класс FileReader наследуется от абстрактного класса Reader и предоставляет функциональность для чтения текстовых файлов.
Для создания объекта FileReader мы можем использовать один из его конструкторов:
| FileReader(String fileName) FileReader(File file) FileReader(FileDescriptorfd) |
А используя методы, определенные в базовом классе Reader, произвести чтение файла:
| import java.io.*; public class FilesApp { public static void main(String[] args) { try(FileReader reader = new FileReader("C:\\SomeDir\\notes3.txt")) { // читаемпосимвольно int c; while((c=reader.read())!=-1){ System.out.print((char)c); } } catch(IOException ex){ System.out.println(ex.getMessage()); } } } |
ВАРИАНТЫ ЗАДАНИЙ
1. Реализовать запись в файл введённой с клавиатуры информации
2. Реализовать вывод информации из файла на экран
3. Заменить информацию в файле на информацию, введённую с клавиатуры
4. Добавить в конец исходного файла текст, введённый с клавиатуры
БИБЛИОГРАФИЧЕСКИЙ СПИСОК
1 Роберт Лафоре, Структуры данных и алгоритмы в Java
2 В. Белов, В. Чистякова Алгоритмы и структуры данных. УчебникИнфра-м 2016 240 стр. ISBN: 5906818256
3 Богачев К.Ю. Основы параллельного программирования– М.: Бином. Лаборатория знаний, 2003. -.342 с.
4 Зыль С.Н. Операционная система реального времени QNX Neutrino: от теории кпрактике – Изд. 2-е - СПб.: БХВ-Петербург, 2004. – 192 с.
БИБЛИОГРАФИЧЕСКИЙ СПИСОК
1. Зорина Н.В. Курс лекций по Объектно-ориентированному программированию на Java, МИРЭА, Москва, 2016
2. Программирование на языке Java: работа со строками и массивами. Методические указания. [Электронный ресурс]: Учебно-методические пособия — Электрон. дан. — СПб.: ПГУПС, 2015. — 24 с.
3. Кожомбердиева, Г.И. Программирование на языке Java: создание графического интерфейса пользователя: учеб. пособие. [Электронный ресурс]: Учебные пособия / Г.И. Кожомбердиева, М.И. Гарина. — Электрон. дан. — СПб.: ПГУПС, 2012. — 67 с.
4. Вишневская, Т.И. Технология программирования. Часть 1. [Электронный ресурс] / Т.И. Вишневская, Т.Н. Романова. — Электрон. дан. — М.: МГТУ им. Н.Э. Баумана, 2007. — 59 с.






