Файл: Что такое generic и для чего они нужны.docx

ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 09.11.2023

Просмотров: 95

Скачиваний: 4

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

Что такое generic и для чего они нужны?

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

Что можно параметризовать?

Что можно параметризировать?

Можно параметризировать только ссылочные типы. Классы /Интерфейсы /Переменные /Массивы

Что нельзя параметризировать?

Нельзя параметризировать примитивы, нельзя параметризировать enum, анонимные классы и классы-исключения (Exception). Невозможно объявить статические поля, типы которых являются параметрами типа. Невозможно использовать приведение или instanceOf с параметризированными типами.

Как параметризовать статический метод?

Как параметризировать статический метод?

Так же, как и обычный метод, но с одним отличием – перед возвращаемым значением должен явно быть указан дженерик. Статические методы не могут иметь или обращаться к generic-полям.

public static void staticMethod(T t) {}

public static T staticMethod (T t) {return ….}

Что такое raw type? К чему приводит использование raw type?

Что такое raw type?

Это имя универсального класса или интерфейса без каких-либо аргументов типа
(пример List<> kist = new ArrayList<>()). Они нужны только для поддержки обратной совместимости кода, «сырые типы» являются не «типобезопасными». В подобную коллекцию можно положить любые типы.

К чему приводит использование raw type?

Придется каждый раз использовать явное приведение типов, отсутствие типобезопасности – что может привести к ошибкам во время Runtime.

Отличие raw type от даймонд оператора?

Если мы используем типизированные типы необходимо всегда использовать diamond синтаксис иначе получим в логе uses unchecked or unsafe operations. Если класс типизирован, всегда указывать тип в дженерике.

Можно ли объявить так: class Animal> {}

Так объявить нельзя. Цель параметризации класса - передать внутрь тип-переменную, которая будет использована внутри класса.
Wildcard для этого не подходит.

Если поле типизировано дженериком как в байт коде будет представлен этот тип?

Экземпляр object

Что такое даймонд оператор?

Оператор <> был введен в Java 7, чтобы сделать код более читабельным и, по сути, является синтаксическим сахаром. <> добавляет вывод типов и уменьшает многословность при использовании дженериков.

Компилятор, видя справа <>, смотрит на левую часть, где расположено объявление типа переменной, в которую присваивается значение. И по этой части понимает, каким типом типизируется значение справа.

Что такое wildcard?

Wildcard — (сильная карта или символом подстановки) это дженерик, обозначается вопросительным знаком в угловых скобках >, означает, что тип может быть чем угодно.

Wildcard может использоваться при создании коллекций
List> exp = new ArrayList();
В параметрах и типе возвращаемого значения метода
List> expMethod(List > e);

Расскажи про иерархию коллекций?

Коллекциями/контейнерами в Java принято называть классы, основная цель которых – хранить набор других элементов





1. Сокращение усилий по разработке благодаря использованию базовых классов коллекций, а не реализации собственных классов коллекций.
2. Качество и безопасность кода улучшается за счет использования хорошо протестированных базовых классов коллекций.
3. Возможность повторного использования и обратная совместимость с прошлыми версиями Java.
4. Поддержка многопоточного доступа.
5. Возможность динамического увлечения размера в отличии от массивов.

Расскажи отличие List от Set?

Set — это неупорядоченное множество уникальных элементов.Например, мешочек с бочонками для игры в лото: каждый номер от 1 до 90 встречается в нём ровно один раз, и заранее неизвестно, в каком порядке бочонки вынут при игре.

List — упорядоченный список, в котором у каждого элемента есть индекс. Дубликаты значений допускаются.Например, последовательность букв в слове: буквы могут повторяться, при этом их порядок важен.

Расскажи отличие ArrayList от LinkedList?

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



Когда лучше использовать ArrayList, а когда LinkedList?

В чём разница между Queue и Deque и Stack?

Queue (одностороняя очередь) - когда элементы можно получить в том порядке, в котором добавляли. FIFO (первым вошёл, первым вышел).

Dequeue (двусторонняя очередь) - можно вставлять/получать элементы из начали и конца.

Stack работает по схеме LIFO (последним вошел, первым вышел). Всякий раз, когда вызывается новый метод, содержащий примитивные значения или ссылки на объекты, то на вершине стека под них выделяется блок памяти.

Отличие двусвязного и односвязного списка?



Как работает HashSet?



HashSet хранит new Object(), потому что в контракте указывается метод remove() который возвращает true, если указанный объект существовал и был удален. Для этого он использует обёртку, HashMap#remove() который возвращает удаленное значение. Если бы вы сохранили null вместо объекта, то вызов HashMap#remove() вернул бы бы null, что было бы неотличимо от результата попытки удалить несуществующий объект, и контракт HashSet.remove() не мог бы быть выполнен.

Как работает метод contains в ArrayList, LinkedList, HashSet?


Метод contains в Arraylist использует метод indexOf (), который использует в свою очередь метод indexOfRange (). Там совершается обход элементов в цикле и если элемент не null, то вызывается стандартный метод equals (сравнение ссылок). Тоже самое для LinkedList.

В методе contains HashSet используются «корзины» и поиск объекта происходит сначала по hashcode, а только потом по equals.

В чём разница между Iterable и Iterator?

Iterable – интерфейс, который реализуют коллекции. У него есть один метод, который производит Iterator.

Iterator — объект с состоянием итерации. Он позволяет вам проверить, есть ли в нем больше элементов, используя hasNext(), и перейти к следующему элементу (если есть), используя next(). Так же есть метод remove().

Что такое Iterator?

В каких случаях нужно использовать iterator? И почему?

Что такое Map? Что должно быть уникальным?

Может ли null быть ключём в HashMap?

HashMap оперирует с null-ключом без каких-либо проблем. Его hash всегда равен 0.


  1. Как работает HashMap?


HashMap работает по принципам хэширования. Хеширование в простейшем представлении, это – способ преобразования любой переменной/объекта в уникальный код после применения любой формулы/алгоритма к их свойствам. Настоящая функция хеширования, должна следовать следующему правилу: Хеш-функция должна возвращать одинаковый хеш-код всякий раз, когда она применена к одинаковым или равным объектам. Другими словами, два одинаковых объекта должны возвращать одинаковые хеш-коды по очереди.
Конструкторы класса:




  1. public HashMap() — создает хеш-отображение по умолчанию: объемом (capacity) = 16 и с коэффициентом загруженности (load factor) = 0.75;


  2. public HashMap(Map< ? extends K, ? extends V> m) — создает хеш-отображение, инициализируемое элементами другого заданного отображения с той начальной емкостью, которой хватит вместить в себя элементы другого отображения;


  3. public HashMap(int initialCapacity) — создает хеш-отображение с заданной начальной емкостью. Для корректной и правильной работы HashMap размер внутреннего массива обязательно должен быть степенью двойки (т.е. 16, 64, 128 и т.д.);


  4. public HashMap(int initialCapacity, float loadFactor) — создает хеш-отображение с заданными параметрами: начальной емкостью и коэффициентом загруженности.

24) Расскажите подробно, как работает метод put в HashMap?

Первым делом, проверяется существует ли ключ (равен ли null). Если ключ не существует (null), значение помещается в таблицу на нулевую позицию, потому что хеш-код для значения null, это – всегда 0.

На следующем шаге, рассчитывается хеш-значение используя хеш-код ключа, получаемый вызовом метода hashCode().

Теперь вызывается функция indexFor(hash, table.length), для вычисления точной позиции (индекса в массиве), куда будет помещен объект Node.

Объекты Node хранятся в форме LinkedList. Когда объект Node должен быть помещен в определенное место, HashMap проверяет нет ли уже в этом месте записи. Если записи нету, то объект помещается в данную позицию. Если все же в данной позиции уже есть объект, то происходит последовательный переход по ссылкам между элементами в цепочке, в поисках последнего элемента, от которого и ставится ссылка на вновь добавленный элемент. Если в списке был найден элемент с таким же ключом, то он заменяется.

Добавление, поиск и удаление элементов выполняется за константное время, при условии, что хеш-функция должна равномерно распределять элементы по корзинам, в этом случае временная сложность для этих 3 операций будет не ниже lg N, а в среднем случае как раз константное время.


25) Как работает метод get в HashMap?

Способ, которым определяется уникальность ключа в методе put(), имеет ту же логику, которую применяет метод get(). Как только HashMap определяет ключ объекта, переданного в аргументе, он просто возвращает значение соответствующего объекта Node. Если же совпадений не найдено, метод get() вернет null.

26) Что происходит при коллизии?

Мы начинаем сравнивать ключ и hashcode текущего объекта и тех которые внутри (если конечно их там несколько). Сначала проверяем равны ли hashcode ключей. Если да, то сравниваем их ключ методом equals.

Если equals возвращает true, значит ключи совпадают по “значению” и hashcode – производится замена, новый объект заменяет тот который уже там находится под тем же ключом,

Если hashcode и “значение” ключа неравны – новый объект добавляется в конец списка.