МІНІСТЕРСТВО ОСВІТИ ТА НАУКИ УКРАЇНИ
НАЦІОНАЛЬНИЙ УНІВЕРСИТЕТ “ЛЬВІВСЬКА ПОЛІТЕХНІКА”
Кафедра САП
Лабораторна робота № 7
З курсу: ,,“Об’єктно-орієнтоване програмування”
на тему:
Використання колекцій в Java
1. МЕТА РОБОТИ
Метою роботи є придбання навиків використання колекцій в програмах на мові Java.
2. КОРОТКІ ТЕОРЕТИЧНІ ВІДОМОСТІ
2.1. Компоненти колекцій
Колекція, іноді звана контейнером, - це об'єкт, який об'єднує декілька елементів в один об'єкт. Колекції використовуються для зберігання даних, доступу і маніпуляцій з даними, а також для передачі даних від одного методу до іншого. Колекція звичайно представляє дані, які представляють природну групу, наприклад телефонний довідник (колекція відповідностей між ім'ям і телефонним номером). Масив також можна розглядати як колекцію, об'єднуючу дані одного типа, елементи якої розташовані послідовно, у порядку зростання індексу.
Всі інтерфейси і класи, що відносяться до колекцій, знаходяться в пакеті java.util.
Схема колекцій (collections framework) - це уніфікована архітектура для уявлення і маніпулювання колекціями. Всі схеми колекцій містять наступні три компоненти:
Інтерфейси - абстрактні типи даних, що представляють колекції. Інтерфейси дозволяють маніпулювати колекціями незалежно від деталей їх уявлення. У Java, як і в інших об'єктно-орієнтованих мовах, ці інтерфейси звичайно утворюють ієрархію.
Реалізації - конкретні реалізації інтерфейсів колекції. За своєю суттю вони є повторно використовуваними структурами даних.
Алгоритми - методи, що виконують деякі корисні дії, наприклад, пошук або сортування, над об'єктами, що реалізовують інтерфейси колекцій. Ці методи називають поліморфними, оскільки один і той же метод може використовуватися в багатьох різних реалізаціях відповідного інтерфейсу колекцій. По суті алгоритми забезпечують повторно використовувану функціональність.
2.2. Інтерфейси колекцій
Ключові інтерфейси колекцій введені, починаючи з JDK 1.2, і використовуються для маніпулювання колекціями, а також для передачі їх від одного методу до іншого. Головною метою цих інтерфейсів є можливість маніпулювання колекціями незалежно від деталей їх реалізації.
Інтерфейси утворюють дві ієрархії.
Інтерфейс Collection є коренем першої ієрархії. Цей інтерфейс представляє групу об'єктів, відомих як його елементи. Деякі реалізації колекцій вирішують дублювання елементів, інші - ні. Пакет SDK не забезпечує прямої реалізації цього інтерфейсу і він використовується для передачі колекцій і маніпулювання ними, коли потрібне максимальне узагальнення.
Окрім цього, для колекцій визначені наступні групові операції
boolean containsAll(Collection з)
boolean addAll(Collection з)
boolean removeAll(Collection з)
boolean retainAll(Collection з)
які дозволяють перевірити, чи містяться всі елементи колекції з в даній колекції; додати всі елементи колекції до даної колекції; видалити з даної колекції всі елементи, що містяться в колекції з або залишити в даній колекції тільки ті елементи, які містяться в колекції з.
Метод iterator повертає об'єкт інтерфейсу Iterator. Інтерфейс Iterator оголошує наступні методи для колекцій: boolean hasNext(), перевіряючий, чи є наступний елемент Object next(), що повертає наступний елемент і void remove(), що видаляє даний елемент.
Нижче наводиться приклад, як об'єкт Iterator використовується для фільтрації колекції, тобто видалення з колекції елементів, що відповідають певним умовам:
static void filter(Collection з)
{
for (Iterator i = з.iterator(); i.hasNext(); )
if (!cond(i.next()))
· i.remove();
}
Даний код є поліморфним, тобто працюватиме для будь-якої колекції, що підтримує видалення елементів, незалежно від реалізації.
Інтерфейс Set є колекцією, яка не повинна містити елементів, що повторюються. Інтерфейс розширює інтерфейс Collection і містить ті ж методи, що і батьківський інтерфейс. Проте методи в цьому інтерфейсі мають конкретніший математичний сенс. Так, наприклад:
вираз s1.containsAll(s2) повертає true, якщо s2 є підмножиною s1;
вираз s1.addAll(s2) перетворить s1 у об'єднання s1 і s2;
вираз s1.retainAll(s2) перетворить s1 у перетин s1 і s2 (перетин двох множин містить елементи, загальні для обох множин);
вираз s1.removeAll(s2) видаляє з s1 всі елементи, що містяться в s2.
Інтерфейс List є впорядкованою колекцією (іноді званою послідовністю). Колекція List може містити впорядковані елементи. На додаток до операцій, успадкованих від колекції, інтерфейс оголошує наступні операції:
отримання значення елементу із заданим індексом (метод public Object get(int index)) і установка значення елементу із заданим індексом (метод public Object set(int index, Object element));
пошук елементу в списку і повернення значення його індексу (методи public int indexOf(Object про) і public int lastIndexOf(Object про));
додавання (метод public void add(int index, Object element)) або видалення (метод public Object remove(int index)) елементу по заданому індексу, а також очищення списку (метод public void clear());
операції над частиною списку (метод public List subList(int fromIndex, int toIndex));
ітераційні операції в списку (метод public ListIterator listIterator() і public ListIterator listIterator(int index)).
Інтерфейс Map є об'єктом, який ставить у відповідність ключам значення. Ключі повинні бути унікальними і їм повинне відповідати єдине значення. Таку колекцію називають відображенням (map), словником (dictionary) або асоціативним масивом (associative array).
Інтерфейс SortedMap є розширенням Map. Елементи для цього інтерфейсу відсортовані в природному порядку або згідно порядку, що задається методами інтерфейсу Comparator.
Інтерфейс реалізує наступні операції (додатково до операцій інтерфейсу Map):
виділення частини відображення (метод public SortedMap subMap(Object fromKey, Object toKey)), головної частини відображення (метод public SortedMap subMap(Object fromKey, Object toKey)) або хвостової частини відображення (метод public SortedMap tailMap(Object fromKey));
отримання першого (метод public Object firstKey()) і останнього (метод public Object lastKey()) елементу відображення;
доступ до інтерфейсу Comparator (метод public Comparator comparator()).
В цілому, інтерфейс SortedMap є аналогом інтерфейсу SortedSet.
2.2. Реалізації колекцій і алгоритми
Реалізації є дійсними об'єктами даних, які утілюють в життя ключові інтерфейси колекцій, описані в попередньому розділі. Існують три типу реалізацій:
спільноцільові реалізації;
пакувальники;
альтернативні (convenience) реалізації.
Спільноцільові реалізації і їх зв'язок з інтерфейсами і структурами даних представлені в таблиці:
Інтерфейс
Реализації
Хеш-таблиця
Змінний масив
Збалансоване дерево
Зв'язаний список
Set
HashSet
TreeSet
LinkedHashSet
List
ArrayList
LinkedList
Map
HashMap
WeekHashMap
TreeMap
LinkedHashMap
Всі реалізації мають не тільки схожі імена, але і схожу поведінку. Всі вони реалізують кожну з операцій, визначених в своєму інтерфейсі. Всі дозволяють використовувати елементи, ключі і значення з константою null.
Основним при реалізації структур даних є вибір інтерфейсу. В більшості випадків вибір реалізації впливає тільки на продуктивність програми. Тому переважним стилем програмування є: спочатку створення колекції, потім вибір реалізації і привласнення нової колекції змінної відповідного інтерфейсного типа (або передача колекції методу, чекаючому аргумент інтерфейсного типа). Таким чином, програма стає незалежною від будь-яких нових методів, що додаються, в даній реалізації, залишаючи за програмістом право зміни реалізації, якщо це необхідно для ефективності програми.
·
2.2.5. Клас HashMap
Клас HashMap є реалізацією інтерфейсу Map з використанням хеш-таблиць і по своїх можливостях відповідає класу HashTable.
Клас HashMap має наступні конструктори:
HashMap() - створює нове, порожнє відображення з місткістю за умовчанням 16 і чинником завантаження, рівним 0.75;
HashMap (Map m) - створює нове відображення, що містить елементи заданого відображення;
HashMap (int initialCapacity) - створює нове, порожнє відображення із заданою місткістю і чинником завантаження, рівним 0.75;
HashMap (int initialCapacity, float loadFactor) - створює нове, порожнє відображення із заданою місткістю і заданим чинником завантаження.
Клас HashMap реалізує наступні методи інтерфейсу Map: clear(), containsKey(), containsValue(), entrySet(), get(), isEmpty(), keySet(), put(), putAll(), remove(), size() і values() .
Iндивідуальне завдання №4
Результат виконання прогарами
Текст програми
MainWindow.java
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.HashMap;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
class MainWindow extends JFrame {
private static final long serialVersionUID = 1L;
private Container c;
private Dimension screenSize;
private Dimension frameSize;
private HashMap bookMap;
private JTextField titleField;
private JTextField authorField;
private JTextField publishingHouseField;
private JTextField yearField;
private JTextField priceField;
private JTextField IDField;
private JButton deleteButton;
private JButton findButton;
private JLabel titleLabel;
private JLabel authorLabel;
private JLabel publishingHouseLabel;
private JLabel yearLabel;
private JLabel priceLabel;
private JLabel IDLabel;
public MainWindow(String str) {
super(str);
c = getContentPane();
setSize(400, 400);
setLayout(new FlowLayout(FlowLayout.LEFT));
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBackground(Color.WHITE);
screenSize = Toolkit.getDefaultToolkit().getScreenSize();
frameSize = getSize();
if (frameSize.height > screenSize.height) {
frameSize.height = screenSize.height;
}
if (frameSize.width > screenSize.width) {
frameSize.width = screenSize.width;
}
setLocation((screenSize.width - frameSize.width) / 2,
(screenSize.height - frameSize.height) / 2);
titleLabel = new JLabel("Title:");
titleLabel.setPreferredSize(new Dimension(150,20));
authorLabel = new JLabel("Author:");
authorLabel.setPreferredSize(new Dimension(150,20));
publishingHouseLabel = new JLabel("Publishing House:");
publishingHouseLabel.setPreferredSize(new Dimension(150,20));
yearLabel = new JLabel("Year:");
yearLabel.setPreferredSize(new Dimension(150,20));
priceLabel = new JLabel("Price");
priceLabel.setPreferredSize(new Dimension(150,20));
IDLabel = new JLabel("ID");
IDLabel.setPreferredSize(new Dimension(150,20));
titleField = new JTextField();
titleField.setEditable(false);
titleField.setPreferredSize(new Dimension(150, 20));
authorField = new JTextField();
authorField.setEditable(false);
authorField.setPreferredSize(new Dimension(150, 20));
publishingHouseField = new JTextField();
publishingHouseField.setEditable(false);
publishingHouseField.setPreferredSize(new Dimension(150, 20));
yearField = new JTextField();
yearField.setEditable(false);
yearField.setPreferredSize(new Dimension(150, 20));
priceField = new JTextField();
priceField.setEditable(false);
priceField.setPreferredSize(new Dimension(150, 20));
IDField = new JTextField();
IDField.setPreferredSize(new Dimension(150, 20));
deleteButton = new JButton("Delete");
deleteButton.setPreferredSize(new Dimension(100,20));
deleteButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String tmpIDString = IDField.getText();
if (bookMap.containsKey(tmpIDString)) {
bookMap.remove(tmpIDString);
JOptionPane.showMessageDialog(null,
"Book was successfully deleted");
IDField.setText("");
clearFields();
}
else
{
JOptionPane.showMessageDialog(null,
"Invalid ID, or book does not exist");
}
}
});
findButton = new JButton("Find");
findButton.setPreferredSize(new Dimension(100,20));
findButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String tmpIDString = IDField.getText();
try {
Book tmpBook = (Book) bookMap.get(tmpIDString);
titleField.setText(tmpBook.getTitle());
authorField.setText(tmpBook.getAuthor());
publishingHouseField.setText(tmpBook.getPublishingHouse());
yearField.setText(tmpBook.getYear() + "");
priceField.setText(tmpBook.getPrice() + "");
} catch (Exception ex) {
JOptionPane.showMessageDialog(null,
"Invalid ID, or book does not exist");
clearFields();
}
}
});
setHashMap();
c.add(titleLabel);
c.add(titleField);
c.add(authorLabel);
c.add(authorField);
c.add(publishingHouseLabel);
c.add(publishingHouseField);
c.add(yearLabel);
c.add(yearField);
c.add(priceLabel);
c.add(priceField);
c.add(IDLabel);
c.add(IDField);
c.add(deleteButton);
c.add(findButton);
setVisible(true);
}
public void setHashMap() {
bookMap = new HashMap();
Book book1 = new Book("Assembler", "author1", "publHouse1", 2001, 50);
Book book2 = new Book("Java", "author2", "publHouse2", 2002, 100);
Book book3 = new Book("Pascal", "author3", "publHouse3", 2003, 49);
Book book4 = new Book("C++", "author4", "publHouse4", 2004, 60);
Book book5 = new Book("Delphi", "author5", "publHouse5", 2005, 80);
Book book6 = new Book("fewfew", "fewfewf", "Fefw", 1990, 00);
bookMap.put("Assembler", book1);
bookMap.put("Java", book2);
bookMap.put("Pascal", book3);
bookMap.put("444", book4);
bookMap.put("555", book5);
bookMap.put("556", book6);
}
private void clearFields() {
titleField.setText("");
authorField.setText("");
publishingHouseField.setText("");
yearField.setText("");
priceField.setText("");
}
}
Book.java
public class Book {
private String title;
private String author;
private String publishingHouse;
private int year;
private int price;
public Book(String title, String author, String _publishingHouse, int year, int price) {
super();
this.title = title;
this.author = author;
this.year = year;
this.price = price;
this.publishingHouse = _publishingHouse;
}
public String getPublishingHouse() {
return publishingHouse;
}
public void setPublishingHouse(String publishingHouse) {
this.publishingHouse = publishingHouse;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
}
Run.java
public class Run {
public static void main(String[] args) {
MainWindow win = new MainWindow("Library");
}
}
Висновок
Отримав навики використання колекцій в програмах на мові Java.