Java, осень 2014: Collections Framework и Generics

45
Collections Framework и Generics Алексей Владыкин 6 октября 2014 Алексей Владыкин Collections 6 октября 2014 1 / 45

description

Обзор стандартных коллекций и их реализации: * Списки, стеки, очереди. * Множества. * Ассоциативные массивы. Generics: * Параметризация классов и методов * Синтаксис и реализация в Java

Transcript of Java, осень 2014: Collections Framework и Generics

Page 1: Java, осень 2014: Collections Framework и Generics

Collections Framework и Generics

Алексей Владыкин

6 октября 2014

Алексей Владыкин Collections 6 октября 2014 1 / 45

Page 2: Java, осень 2014: Collections Framework и Generics

1 Generics

2 Collections Framework

Алексей Владыкин Collections 6 октября 2014 2 / 45

Page 3: Java, осень 2014: Collections Framework и Generics

Generics

Алексей Владыкин Collections 6 октября 2014 3 / 45

Page 4: Java, осень 2014: Collections Framework и Generics

Generics

Возможность параметризовать класс или метод каким-либотипом

Напоминает шаблоны в C++, но есть большие отличия(нельзя использовать примитивные типы и их значения)

Поддержка добавлена в Java 5

Алексей Владыкин Collections 6 октября 2014 4 / 45

Page 5: Java, осень 2014: Collections Framework и Generics

Generics

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

package java.lang.ref;

public abstract class Reference <T> {

private T referent;

Reference(T referent) {this.referent = referent;

}

public T get() {return referent;

}}

Алексей Владыкин Collections 6 октября 2014 5 / 45

Page 6: Java, осень 2014: Collections Framework и Generics

Generics

WeakReference <Integer > ref = new WeakReference < >(1000);System.out.printf("Initial value: %s\n", ref.get ());int gcCount = 0;do {

System.gc();gcCount ++;System.out.printf(

"Value after GC #%d: %s\n",gcCount , ref.get ());

} while (ref.get() != null);

Алексей Владыкин Collections 6 октября 2014 6 / 45

Page 7: Java, осень 2014: Collections Framework и Generics

Generics

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

package java.util;

public class Collections {

public static <T> List <T> nCopies(int n, T o){// ...

}}

Алексей Владыкин Collections 6 октября 2014 7 / 45

Page 8: Java, осень 2014: Collections Framework и Generics

Generics

Реализация

Реализация generic’ов в Java основана на «type erasure»

Для generic класса или метода генерируется только один вариант,вне зависимости от количества разных параметризаций

На этапе компиляции выполняются проверки типов идобавляются необходимые приведения типов

Алексей Владыкин Collections 6 октября 2014 8 / 45

Page 9: Java, осень 2014: Collections Framework и Generics

Generics

Что генерирует компилятор

package java.lang.ref;

public abstract class Reference {

private Object referent;

Reference(Object referent) {this.referent = referent;

}

public Object get() {return referent;

}}

Алексей Владыкин Collections 6 октября 2014 9 / 45

Page 10: Java, осень 2014: Collections Framework и Generics

Generics

WeakReference ref = new WeakReference (1000);System.out.printf("Initial value: %s\n",

(Integer) ref.get ());int gcCount = 0;do {

System.gc();gcCount ++;System.out.printf(

"Value after GC #%d: %s\n",gcCount , (Integer) ref.get ());

} while (( Integer) ref.get() != null);

Алексей Владыкин Collections 6 октября 2014 10 / 45

Page 11: Java, осень 2014: Collections Framework и Generics

Generics

Ограничения

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

T obj = new T(); // compilation error

T[] arr = new T[0]; // compilation error

Во время исполнения информация о generic-параметрахнедоступна

if (obj instanceof T) // compilation error

Алексей Владыкин Collections 6 октября 2014 11 / 45

Page 12: Java, осень 2014: Collections Framework и Generics

Generics

Поддержка наследования

Если class Integer extends Number, то:

Number number = new Integer (1); // OKNumber [] numberArray = new Integer [0]; // OK

Reference <Number > ref =new WeakReference <Integer >(1); // not OK!

Reference <? extends Number > ref2 =new WeakReference <Integer >(1); // OK

Алексей Владыкин Collections 6 октября 2014 12 / 45

Page 13: Java, осень 2014: Collections Framework и Generics

Generics

package java.util;

public class Collections {

public static <T> void copy(List <? super T> dest ,List <? extends T> src) {

// ...}

}

Алексей Владыкин Collections 6 октября 2014 13 / 45

Page 14: Java, осень 2014: Collections Framework и Generics

Collections Framework Общие сведения

Алексей Владыкин Collections 6 октября 2014 14 / 45

Page 15: Java, осень 2014: Collections Framework и Generics

Collections Framework Общие сведения

Что такое коллекции

Разнообразные контейнеры для хранения наборов объектов,более удобные, чем массивы

добавление/удаление элементовread-only коллекцииоперации поиска, объединения, вычитанияподдержка разнообразных специальных случаев

В отличие от массивов, могут хранить только объекты.Для примитивных типов — классы-обертки и autoboxing

Пакет java.util

Алексей Владыкин Collections 6 октября 2014 15 / 45

Page 16: Java, осень 2014: Collections Framework и Generics

Collections Framework Общие сведения

java.util.Collection

Базовый интерфейс для коллекций

Основные операции:int size()boolean isEmpty()boolean contains(Object o)boolean add(E e)boolean remove(Object o)void clear()

Object.equals()

Алексей Владыкин Collections 6 октября 2014 16 / 45

Page 17: Java, осень 2014: Collections Framework и Generics

Collections Framework Общие сведения

java.util.Iterator

Единообразный способ обхода элементов коллекции

Операции:boolean hasNext()E next()void remove()

Алексей Владыкин Collections 6 октября 2014 17 / 45

Page 18: Java, осень 2014: Collections Framework и Generics

Collections Framework Общие сведения

Использование итератора

// foreach syntaxfor (E element : collection) {

System.out.println(element );}

// equivalent toIterator <E> it = collection.iterator ();while (it.hasNext ()) {

E element = it.next ();System.out.println(element );

}

Алексей Владыкин Collections 6 октября 2014 18 / 45

Page 19: Java, осень 2014: Collections Framework и Generics

Collections Framework Общие сведения

Разновидности коллекций

List — список(фиксированный порядок, доступ к элементам по индексу)

Queue, Deque — очередь и дек(доступ к элементам с начала и с конца)

Set — множество(каждый элемент встречается не более одного раза)

Map — ассоциативный массив(набор пар «ключ–значение»)

Алексей Владыкин Collections 6 октября 2014 19 / 45

Page 20: Java, осень 2014: Collections Framework и Generics

Collections Framework Списки

java.util.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<E> subList(int fromIndex, int toIndex)

equals: списки равны, если содержат равные элементы водинаковом порядке

Алексей Владыкин Collections 6 октября 2014 20 / 45

Page 21: Java, осень 2014: Collections Framework и Generics

Collections Framework Списки

java.util.ArrayList

Реализация списка на основе массиваСпецифические операции:

void ensureCapacity(int capacity)void trimToSize()

Эффективный доступ к элементу по индексуВставка/удаление по индексу имеет линейную трудоемкость

List <String > words = new ArrayList <>();words.add("one");words.set(0, "two");words.add(0, "three");words.remove (1);

Алексей Владыкин Collections 6 октября 2014 21 / 45

Page 22: Java, осень 2014: Collections Framework и Generics

Collections Framework Списки

java.util.LinkedList

Реализация списка на основе двусвязного списка

Эффективные вставка и удаление элемента в начале и в концеспискаДоступ к элементу по индексу имеет линейную трудоемкость

List <String > words = new LinkedList <>();words.add("one");words.add("two");words.add("three");words.subList(1, 3). clear ();

Алексей Владыкин Collections 6 октября 2014 22 / 45

Page 23: Java, осень 2014: Collections Framework и Generics

Collections Framework Очереди

java.util.Queue

First In — First Out (FIFO)

Операции:boolean offer(E e)E peek()E poll()

Алексей Владыкин Collections 6 октября 2014 23 / 45

Page 24: Java, осень 2014: Collections Framework и Generics

Collections Framework Очереди

java.util.PriorityQueue

Реализация очереди с приоритетами на основе двоичной кучи

offer и poll работают за O(log(N))

Извлекается элемент с минимальным значением

PriorityQueue <Integer > pq = new PriorityQueue <>();pq.offer (3);pq.offer (2);pq.offer (1);

Integer element;while (( element = pq.poll ()) != null) {

System.out.println(element );}

Алексей Владыкин Collections 6 октября 2014 24 / 45

Page 25: Java, осень 2014: Collections Framework и Generics

Collections Framework Очереди

java.util.Deque

Стек и очередь в одном флаконе

Операции:boolean offerFirst(E e)E peekFirst()E pollFirst()boolean offerLast(E e)E peekLast()E pollLast()

Алексей Владыкин Collections 6 октября 2014 25 / 45

Page 26: Java, осень 2014: Collections Framework и Generics

Collections Framework Очереди

java.util.ArrayDeque

Реализация дека на основе массива

Рекомендованный класс для обычной очереди и стека

Deque <Integer > pq = new ArrayDeque <>();pq.offerLast (3);pq.offerLast (2);pq.offerLast (1);

Integer element;while (( element = pq.pollFirst ()) != null) {

System.out.println(element );}

Алексей Владыкин Collections 6 октября 2014 26 / 45

Page 27: Java, осень 2014: Collections Framework и Generics

Collections Framework Множества

java.util.Set

Каждый элемент встречается не более одного раза

Не добавляет новых операций к тем, что естьв java.util.Collection

Но гарантирует, что при добавлении элементов дубликатыне появятся

equals: множества равны, если содержат одинаковые элементы

Алексей Владыкин Collections 6 октября 2014 27 / 45

Page 28: Java, осень 2014: Collections Framework и Generics

Collections Framework Множества

java.util.HashSet

Реализация множества на основе хеш-таблицыПорядок обхода элементов непредсказуем

Set <String > words = new HashSet <>();words.add("one");words.add("one");words.add("two");words.add("two");

Алексей Владыкин Collections 6 октября 2014 28 / 45

Page 29: Java, осень 2014: Collections Framework и Generics

Collections Framework Множества

java.util.LinkedHashSet

Реализация множества на основе хеш-таблицыПорядок обхода элементов определяется порядком вставки

Set <String > words = new LinkedHashSet <>();words.add("one");words.add("one");words.add("two");words.add("two");

Алексей Владыкин Collections 6 октября 2014 29 / 45

Page 30: Java, осень 2014: Collections Framework и Generics

Collections Framework Множества

Специфика хеш-таблиц

Контракт equals() и hashCode():если a.equals(b), то a.hashCode()==b.hashCode()

Пока объект находится в хеш-таблице, нельзя менять его поля,влияющие на значение hashCode()

Алексей Владыкин Collections 6 октября 2014 30 / 45

Page 31: Java, осень 2014: Collections Framework и Generics

Collections Framework Множества

java.util.TreeSet

Реализация множества на основе дерева поискаЭлементы хранятся отсортированными

SortedSet <String > words = new TreeSet <>();words.add("aaa");words.add("bbb");words.add("ccc");words.headSet("bbb").clear ();

Алексей Владыкин Collections 6 октября 2014 31 / 45

Page 32: Java, осень 2014: Collections Framework и Generics

Collections Framework Множества

Специфика деревьев поиска

Порядок элементов определяется:объектом типа java.util.Comparatorс методом int compare(T o1, T o2)методом элементов int compareTo(T o) (элементы должныреализовать интерфейс java.lang.Comparable)

Пока объект находится в дереве, нельзя менять его поля,влияющие на вычисление compareTo(T)

Контракт equals() и compareTo():a.equals(b) == (a.compareTo(b) == 0)

Алексей Владыкин Collections 6 октября 2014 32 / 45

Page 33: Java, осень 2014: Collections Framework и Generics

Collections Framework Множества

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

List <String > list = new ArrayList <>();list.add("aaa");list.add("aaa");list.add("bbb");list.add("aaa");

Set <String > set =new LinkedHashSet <>(list);

List <String > listWithoutDups =new ArrayList <>(set);

Алексей Владыкин Collections 6 октября 2014 33 / 45

Page 34: Java, осень 2014: Collections Framework и Generics

Collections Framework Ассоциативные массивы

java.util.Map

Набор пар «ключ–значение»Не наследует java.util.Collection

Основные операции: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 value)Set<K> keySet()Collection<V> values()Set<Map.Entry<K, V>> entrySet()

equals: равны, если содержат одинаковые пары «ключ-значение»

Алексей Владыкин Collections 6 октября 2014 34 / 45

Page 35: Java, осень 2014: Collections Framework и Generics

Collections Framework Ассоциативные массивы

java.util.HashMap

Реализация ассоциативного массива на основе хеш-таблицыПорядок обхода элементов непредсказуемЕсть java.util.LinkedHashMap

Map <String , String > dictionary = new HashMap <>();dictionary.put("foo", "bar");dictionary.put("bar", "baz");dictionary.remove("bar");

Алексей Владыкин Collections 6 октября 2014 35 / 45

Page 36: Java, осень 2014: Collections Framework и Generics

Collections Framework Ассоциативные массивы

java.util.TreeMap

Реализация ассоциативного массива на основе дерева поискаЭлементы хранятся отсортированными по ключу

SortedMap <String , String > dictionary =new TreeMap <>();

dictionary.put("foo", "bar");dictionary.put("bar", "baz");dictionary.subMap("bar", "foo").clear ();

Алексей Владыкин Collections 6 октября 2014 36 / 45

Page 37: Java, осень 2014: Collections Framework и Generics

Collections Framework Ассоциативные массивы

Обход ассоциативного массива

Map <A, B> map = new HashMap <>();

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

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

for (Map.Entry <A, B> entry : map.entrySet ()) {entry.getKey ();entry.getValue ();

}

Алексей Владыкин Collections 6 октября 2014 37 / 45

Page 38: Java, осень 2014: Collections Framework и Generics

Collections Framework Ассоциативные массивы

Устаревшие классы

java.util.Vector

java.util.Stack

java.util.Dictionary

java.util.Hashtable

Алексей Владыкин Collections 6 октября 2014 38 / 45

Page 39: Java, осень 2014: Collections Framework и Generics

Collections Framework Рецепты

Сборник рецептов

Алексей Владыкин Collections 6 октября 2014 39 / 45

Page 40: Java, осень 2014: Collections Framework и Generics

Collections Framework Рецепты

Как отсортировать список

// move elements randomlyCollections.shuffle(list);

// list is sorted in -placeCollections.sort(list);

Алексей Владыкин Collections 6 октября 2014 40 / 45

Page 41: Java, осень 2014: Collections Framework и Generics

Collections Framework Рецепты

Как запретить изменение

Set <String > set =Collections.unmodifiableSet(originalSet );

set.remove("abc");// throws UnsupportedOperationException

Алексей Владыкин Collections 6 октября 2014 41 / 45

Page 42: Java, осень 2014: Collections Framework и Generics

Collections Framework Рецепты

Как перелить коллекцию в массив

// List <Integer > list

Integer [] array =list.toArray(new Integer[list.size ()]);

Алексей Владыкин Collections 6 октября 2014 42 / 45

Page 43: Java, осень 2014: Collections Framework и Generics

Collections Framework Рецепты

Как перелить массив в коллекцию

String [] array = {"A", "B", "C"};

Set <String > set1 =new HashSet <>(Arrays.asList(array ));

Set <String > set2 = new HashSet <>();Collections.addAll(set2 , array);

Алексей Владыкин Collections 6 октября 2014 43 / 45

Page 44: Java, осень 2014: Collections Framework и Generics

Collections Framework Рецепты

Autoboxing

Автоматическая упаковка примитивных типов в обертки ираспаковка обратно

List <Integer > list = new ArrayList <>();for (int i = 0; i < 10; ++i) {

list.add(i);}for (int i = 0; i < 10; ++i) {

list.remove(i); // ooops}

Алексей Владыкин Collections 6 октября 2014 44 / 45

Page 45: Java, осень 2014: Collections Framework и Generics

Что сегодня узнали

Можно хранить наборы объектов не только в массивах, но и вболее гибких и функциональных коллекциях

В стандартной библиотеке Java есть списки, множества иассоциативные массивы

Работа с коллекциями стала намного удобнее с появлениемGeneric’ов в Java 5

Алексей Владыкин Collections 6 октября 2014 45 / 45