Главная страница
Навигация по странице:

  • Итератор стоит использовать тогда, когда нужно удалить какой-либо элемент

  • // Output

  • Вставка элемента add(e) offer(e) Удаление элемента

  • Сделать задания 1, 2, 3

  • НЕ реализует интерфейс collection

  • HashMap, LinkedHashMap, TreeMap

  • Сделать задания 4, 5

  • Лабораторная работа 4 Коллекции объектов


    Скачать 152.03 Kb.
    НазваниеЛабораторная работа 4 Коллекции объектов
    Дата16.05.2023
    Размер152.03 Kb.
    Формат файлаpptx
    Имя файлаLR_4.pptx
    ТипЛабораторная работа
    #1136175

    Лабораторная работа 4 Коллекции объектов

    Коллекции

    Коллекции – это контейнеры, в которых можно хранить условно однотипные* объекты. Отличия от массивов:

    • Предоставляют значительно больше возможностей для хранения и управления элементами, чем массивы
    • Имеют возможность добавления и удаления элементов с динамическим изменением размера коллекции
    • Могут хранить только объекты, но не примитивные типы (однако, можно использовать классы-обертки)
    • Работают медленнее, чем массивы
    • *Элементы коллекции должны иметь одинаковый базовый класс

    Основные типы коллекций

    • Java.util.List – список (хранит элементы в порядке вставки, доступ к ним осуществляется по индексу)
    • java.util.Set – множество (каждый элемент встречается не более одного раза)
    • java.util.Queue – очередь (выдает элементы в порядке вставки элементов в очередь, FIFO – First In, First Out)
    • java.util.Map – ассоциативный массив (словарь, набор пар «ключ-значение»)

    Иерархия классов коллекций

    Базовый интерфейс Collection

    Основные операции:

    • int size()
    • boolean isEmpty()
    • boolean contains(Object o)
    • boolean add(E e)
    • boolean remove(Object o)
    • void clear()

    Iterator

    Итератор используется для того, чтобы получить доступ к элементам коллекции. Итератор можно получить из любой коллекции, вызвав у нее метод iterator().

    Iterator содержит следующие методы:

    boolean hasNext()

    E next()

    void remove()

    Однако, в большинстве случаев удобнее пользоваться циклом foreach для перебора элементов коллекции. Итератор стоит использовать тогда, когда нужно удалить какой-либо элемент. Если попробовать удалить его в цикле, программа, скорее всего, выдаст ошибку и аварийно завершит работу.

    Java.util.List

    List

    • Хранит элементы в порядке вставки
    • Доступ к элементам осуществляется по индексу
    • Основные операции:

      E get(int index)

      E set(int index, E element)

      void add(int index, E element)

      E remove(int index)

      int indexOf(Object o)

      int lastIndexOf(Object o)

      List subList(int fromIndex, int toIndex)

      Подклассы:

    • ArrayList
    • LinkedList
    • Vector

    ArrayList

    ArrayList – это список, реализованный на основе массива.

    Преимущества:

    • Возможность доступа к произвольному элементу по индексу за постоянное время (так как это массив),
    • Минимум затрат ресурсов при хранении такого списка
    • Вставка в конец списка и удаление производится за постоянное время, если размер списка заранее определен при помощи метода ensureCapacity(), либо при помощи передачи резервируемого объема памяти в конструктор.
    • Недостатки:

    • при вставке n+1 элемента в список размера n приходится перезаписывать массив, что замедляет работу программы
    • при вставке/удалении элемента в середине списка происходит перезапись всех элементов размещенных «правее» в списке на одну позицию влево
    • при удалении элементов размер массива не уменьшается, до явного вызова метода trimToSize()

    Пример ArrayList

    ArrayList words = new ArrayList();

    words.add(“one”);

    words.set(0, “two”);

    words.add(0, “three”);

    words.remove(1);

    // В итоге в списке останется элемент с индексом 0 и значением “three”

    LinkedList

    LinkedList – это двусвязный список, основанный на работе с объектами и ссылками между ними (каждый объект хранит ссылки на предыдущее и следующее значения).

    Преимущества:

    • Может выполнять вставку/удаление элементов в списке за постоянное время
    • Доступ к первому и последнему элементу списка также осуществляется за постоянное время
    • Недостатки:

    • Доступ к произвольному элементу имеет линейную трудоемкость
    • В целом LinkedList проигрывает ArrayList и по потребляемой памяти и по скорости выполнения операций. LinkedList предпочтительно применять, когда происходит активная работа (вставка/удаление) с серединой списка или в случаях, когда необходимо гарантированное время добавления элемента в список.

    Пример LinkedList

    сlass Apple {

    String mSort;

    Apple(String sort) {

    mSort = sort;

    }

    String getSort() {

    return mSort;

    }

    }

    // В методе main():

    List apples = new LinkedList();

    apples.add(new Apple(“Macintosh”));

    apples.add(new Apple(“Granny smith”));

    apples.add(new Apple(“Antonovka”));

    for (Apple a : apples)

    System.out.println(“Apple sort – “ + a.getSort());

    Пример использования итератора

    List list = new ArrayList();

    for (int i = 0; i < 5; i++)

    list.add("Str "+i);

    System.out.println("Before: "+list.toString());

    Iterator it = list.iterator();

    while(it.hasNext()) {

    if (it.next().toString().contains("3"))

    it.remove();

    }

    System.out.println("After: "+list.toString());

    Сортировка списков

    Список можно отсортировать при помощи метода Collections.sort(), который имеет два перегруженных варианта:

    sort(List list)

    sort(List list, Comparator c)

    Первый вариант метода сортирует строки и числа по возрастанию. Для того, чтобы задать свой способ сортировки или отсортировать объекты созданных классов, необходимо реализовать интерфейс Comparable и передать его методу sort(). Пример:

    Collections.sort(list, new Comparator() {

    public int compare(String o1, String o2) {

    Integer i1 = Integer.parseInt(o1);

    Integer i2 = Integer.parseInt(o2);

    return (i1 > i2 ? -1 : (i1 == i2 ? 0 : 1));

    }

    });

    java.util.Set

    Set

    Множество – это контейнер, в котором каждый элемент хранится только в одном экземпляре. Такой вид коллекции часто используется для проверки принадлежности объекта заданному множеству. Следовательно, важнейшей операции является операция поиска, поэтому на практике обычно выбирается множество типа HashSet, оптимизированная для быстрого поиска. Особенности:
    • Каждый элемент встречается не более одного раза (гарантирует, что при добавлении элементов, дубликаты не появятся)
    • Не добавляет новых операций к тем, что есть в интерфейсе Collection

    HashSet и LinkedHashSet

    Особенности HashSet:

    • Реализация множества на основе хеш-таблицы
    • Порядок обхода элементов непредсказуем
    • LinkedHashSet аналогичен HashSet. Отличие заключается в том, что порядок обхода элементов определяется порядком вставки

      Set
      figures = new HashSet();

      Set cars = new LinkedHashSet();

    TreeSet

    Особенности:

    • Реализация множества на основе дерева поиска
    • Элементы хранятся отсортированными
    • Хранить можно числа и строки
    • SortedSet words = new TreeSet();

      words.add(“bbb”);

      words.add(“aaa”);

      words.add(“ccc”);

      words.headSet(“bbb”).clear();

    Удаление дубликатов из коллекции

    List animals = new ArrayList();

    animals.add("Cat");

    animals.add("Dog");

    animals.add("Cat");

    animals.add("Hamster");

    Set tmpSet = new HashSet(animals);

    animals = new ArrayList(tmpSet);

    System.out.print (animals);

    // Output

    [Cat, Dog, Hamster]

    Сортировка множеств

    Отсортировать множество можно двумя способами:

    • Изначально использовать множество TreeSet (при этом конструктору можно передать собственную реализацию интерфейса Comparator)
    • Создать новое множество TreeSet и передать ему в конструктор существующее множество. Пример:
    • Set unsortedSet = new HashSet();

      unsortedSet.add("bbb");

      unsortedSet.add("ddd");

      unsortedSet.add("ccc");

      unsortedSet.add("aaa");

      System.out.println(unsortedSet); // Output: [aaa, ddd, ccc, bbb]

      SortedSet sortedSet = new TreeSet(unsortedSet);

      System.out.println(sortedSet); // Output: [aaa, bbb, ccc, ddd]

    Queue

    Queue (очередь) обычно представляет собой контейнер, работающий по принципу Last In, First Out (LIFO). Иначе говоря, элементы заносятся в очередь с одного «конца» и извлекаются с другого в порядке их поступления. Очереди часто используются для реализации надежной передачи объектов между разными областями программы. Интерфейс Queue реализуется в классах LinkedList и PriorityQueue.

    Основные операции представлены в таблице:


    Выбрасывает исключение

    Возвращает значение

    Вставка элемента

    add(e)

    offer(e)

    Удаление элемента

    remove()

    poll()

    Получение элемента

    element()

    peek()

    Пример Queue

    Queue qc = new LinkedList();

    for (char c : "Dinosaurus".toCharArray())

    qc.offer(c);

    while(qc.peek() != null)

    System.out.print(qc.remove()+" ");

    // Output: D i n o s a u r u s


    Сделать задания 1, 2, 3

    java.util.Map

    Map

    Карта отображает одни объекты на другие. По сути это ассоциативный массив, в котором доступ к объекту можно получить зная его ключ (набор пар «ключ-значение»). Map – это интерфейс и он НЕ реализует интерфейс collection, в отличие от всех остальных типов коллекций (см схему на 4 слайде). Для того, чтобы начать работать с картной, необходимо создать объект одного из классов: HashMap, LinkedHashMap, TreeMap или HashTable.

    Основные операции, описанные в Map

    • int size()
    • boolean isEmpty()
    • V get(Object key)
    • V put(K key, V value)
    • V remove(Object key)
    • boolean containsKey(Object key)
    • boolean containsValue(Object key)
    • Set keySet()
    • Collection values()
    • Set> entrySet()

    HashMap и LinkedHashMap

    Особенности:

    • Реализация ассоциативного массива на основе хеш-таблицы
    • Порядок обхода элементов непредсказуем (HashMap) либо обусловлен порядком вставки (LinkedHashMap)
    • Map planets = new HashMap();

      // Autoboxing: автоматическая упаковка примитивных типов в

      // классы-обертки (в данном случае int -> Integer)

      planets.put(“Mercury", 58);

      planets.put(“Venus", 108);

      planets.put(“Earth", 150);

      planets.put(“Mars”, 228);

      int distanceToSun = planets.get(“Earth");

    Пример работы с Map

    Map vehicles = new HashMap();

    vehicles.put("BMW", 250);

    vehicles.put("Mercedes", 235);

    vehicles.put("Audi", 245);

    vehicles.put(“Lada", 170);

    vehicles.remove(“Lada“);

    System.out.println("Total vehicles: " + vehicles.size());

    // Получаем множество ключей и перебираем коллекцию

    for (String key : vehicles.keySet())

    System.out.println(key + " - " + vehicles.get(key));

    System.out.println();

    // Ищем элемент с ключем “Audi”

    String searchKey = "Audi";

    if (vehicles.containsKey(searchKey))

    System.out.println(searchKey+" max speed is”+vehicles.get(searchKey)+”km/h");

    // Удаляем все элементы

    vehicles.clear();

    TreeMap

    Особенности:

    • Реализация ассоциативного массива на основе дерева поиска
    • Элементы хранятся отсортированными по ключу
    • SortedMap treeMap = new TreeMap();

      treeMap.put("Bruce", "Willis");

      treeMap.put("Arnold", "Schwarzenegger");

      treeMap.put("Jackie", "Chan");

      treeMap.put("Sylvester", "Stallone");

      treeMap.put("Chuck", "Norris");

      for (Map.Entry e : treeMap.entrySet())

      System.out.println(e.getKey() + " " + e.getValue());


    Output:

    Arnold Schwarzenegger

    Bruce Willis

    Chuck Norris

    Jackie Chan

    Sylvester Stallone

    Сортировка карт

    Чтобы отсортировать карту по ключам*, необходимо:

    • Изначально использовать карту TreeMap (при этом конструктору можно передать собственную реализацию интерфейса Comparator)
    • Создать новую карту TreeMap и передать ей в конструктор существующую коллекцию. Пример:
    • Map vehicles = new HashMap();

      vehicles.put("BMW", 250);

      vehicles.put("Mercedes", 235);

      vehicles.put("Audi", 245);

      System.out.println(vehicles); // Output: {Audi=4, BMW=5, Mercedes=3}

      SortedMap sortedVechicles = new TreeMap(vehicles);

      System.out.println(sortedVechicles); //Output: {Audi=4, BMW=5, Mercedes=3}

      * По значениям карту можно отсортировать только вручную

    Методы обхода ассоциативного массива

    Map map = new HashMap();

    1) for (A key : map.keySet()) { … }

    2) for (B value : map.values()) { … }

    3) for (Map.Entry entry : map.entrySet()) {

    entry.getKey();

    entry.getValue();

    }

    Сравнение коллекций

    Для сравнения используется метод equals(Object o):

    • Списки равны, если содержат равные элементы в одинаковом порядке
    • Множества равны, если содержат одинаковые элементы
    • Карты (ассоциативные массивы) равны, если содержат одинаковые пары «ключ-значение»
    • List firstList = new ArrayList();

      // add elements...

      List secondList = new ArrayList();

      // add elements...

      if (firstList.equals(secondList))

      System.out.println("Collections are equal!");

    Пример создания составных коллекций

    // Список

    List arrayList = new ArrayList();

    // Карта, в которой ключом является объект String, а значением - список

    Map> innerMap = new HashMap>();

    // Список, элементами которого являются карты, в которых ключом являются

    // объекты типа String, а значением – список

    List>> listOfMaps =

    new ArrayList>>();

    arraylist.add("Text");

    innerMap.put("key", arraylist);

    listOfMaps.add(innerMap);

    // Извлекаем…

    String text = listOfMaps.get(0).get("key").get(0);

    System.out.println("Таки извлекли: "+ text);

    Параметризованные классы (Generics)

    class GenericClass {

    private T item;

    T getItem() {

    return item;

    }

    void setItem(T item) {

    this.item = item;

    }

    }

    // Создаем экземпляр класса

    GenericClass gc = new GenericClass();

    gc.setItem("Some string"); // T -> String

    System.out.println(gc.getItem()); //Output: Some string

    gc.setItem(42); // T -> Integer

    System.out.println(gc.getItem()); //Ouput: 42

    Параметризованные методы

    static void fromArrayToCollection(T[] a, Collection c) {

    for (T element : a) c.add(element);

    }

    // Вызываем метод fromArrayToCollection()

    String[] strArr = new String[10];

    Collection objColl = new ArrayList();

    fromArrayToCollection(strArr, objColl); // T -> String

    Integer[] intArr = new Integer[10];

    Double[] doubleArr = new Double[10];

    Collection numColl = new ArrayList();

    fromArrayToCollection(intArr, numColl); // T -> Integer

    fromArrayToCollection(doubleArr, numColl); // T -> Double

    Еще один пример с параметризованными типами

    class Parent {

    }

    class Child extends Parent {

    }

    List
    list = new ArrayList(); // Ошибка!

    List list = new ArrayList(); //ОК


    Сделать задания 4, 5

    Задания

    1. Создайте класс Student, содержащий закрытые поля name, age, averageScore, конструктор, который инициализирует эти поля и get- методы для получения значений этих полей. В методе main() создайте список List с типом в цикле (y/n) введите с клавиатуры параметры для 3-4 студентов и добавьте их в коллекцию. После этого нужно выбрать студента с самым высоким средним баллом и вывести полную информацию о нем на экран. 2. Задана строка “Java is a programming language that is concurrent, class-based and object-oriented.”. Разбить ее на слова, убрать знаки препинания. Создать множество, состоящее из этих слов. Удалить все слова, длина которых три символа и меньше (чтобы не возникало ошибок, следует использовать итератор). Вывести получившиеся слова в отсортированном виде. 3. Создать очередь Queue типа Character, записать в нее несколько случайных символов, затем вытащить их из очереди и вывести на экран. Для создания случайных символов можно приводить случайные числа типа int к переменным типа char при помощи явного приведения типов.

    Задания

    4. Создать карту Map, содержащую данные любых типов. Вывести все ключи. Вывести все значения. Программа должна предлагать ввести ключ и выводить на экран значение, соответствующее этому ключу, затем наоборот: предлагать ввести значение и выдавать ключ. Если в коллекции нет такого ключа или значения, программа должна выдавать соответствующие уведомления. 5. Создать метод printArray(), который получает массив любого типа (кроме примитивных типов) и выводит на экран каждый элемент. Аналогично создать метод printCollection(). В методе main() создать несколько массивов и коллекций различных типов и вывести на экран их элементы при помощи созданных методов.

    Домашнее задание

    • Создать класс Planet, содержащий закрытые поля distanceToSun, mass и diameter, конструктор, который инициализирует эти поля (расстояние до солнца, масса и диаметр) и get- и set-методы для этих полей. Создать карту Map , который будет содержать название планеты и класс с информацией о ней. Добавить в карту несколько планет (в коде, а не с клавиатуры). Программа должна предлагать ввести имя планеты и выдавать информацию о ней. Если такой планеты нет в списке, программа должна выдавать соответствующее сообщение.
    • Сделать то же самое, что и в предыдущей задаче, но информация о планете должна храниться в элементах списка. То есть коллекция должна быть примерно такой: Map>.


    написать администратору сайта