Что лучше, ArrayList или LinkedList?
Самый избитый вопрос. Проверяет знание особенностей реализации (кишки ArrayList, кишки LinkedList) и эффективности операций в этих разных реализациях. В вопрос иногда добавляют
Стоит добавить, что для работы на краях лучше использовать реализации специально для этого спроектированного интерфейса Deque: например реализующую кольцевой буфер
Самый избитый вопрос. Проверяет знание особенностей реализации (кишки ArrayList, кишки LinkedList) и эффективности операций в этих разных реализациях. В вопрос иногда добавляют
Vector
– пересинхронизированный и устаревший вариант ArrayList
, который лучше заменить Collections.synchronizedList()
.ArrayList
хранит данные в массиве, LinkedList
в двусвязном списке. Из этого вытекает разница в эффективности разных операций: ArrayList
лучше справляется с изменениями в середине и ростом в пределах capacity, LinkedList
– на краях. В целом обычно ArrayList лучше.Стоит добавить, что для работы на краях лучше использовать реализации специально для этого спроектированного интерфейса Deque: например реализующую кольцевой буфер
ArrayDeque
.👍7🔥3👎2❤1
Forwarded from Академия Кода
Какие типы Java могут имплементировать интерфейсы?
В Java нет концепции множественного наследования, но с помощью интерфейса мы можем его добиться. По сути, интерфейс - это именованный набор определений без реализации. Интерфейс в Java - это особый вид класса. Подобно классам, интерфейс содержит методы и члены; в отличие от классов, в интерфейсе все члены являются окончательными, а все методы абстрактными.
В основном существуют 5 типов Java, которые могут реализовывать интерфейсы:
1. Обычный класс
2. Абстрактный класс
3. Вложенный класс
4. Enum
5. Динамический прокси
Подписывайтесь на канал 👉@coddy_academy
#java
В Java нет концепции множественного наследования, но с помощью интерфейса мы можем его добиться. По сути, интерфейс - это именованный набор определений без реализации. Интерфейс в Java - это особый вид класса. Подобно классам, интерфейс содержит методы и члены; в отличие от классов, в интерфейсе все члены являются окончательными, а все методы абстрактными.
В основном существуют 5 типов Java, которые могут реализовывать интерфейсы:
1. Обычный класс
2. Абстрактный класс
3. Вложенный класс
4. Enum
5. Динамический прокси
Подписывайтесь на канал 👉@coddy_academy
#java
👍2
Когда идти в IT, если не сейчас?
Начать карьеру востребованного разработчика на Java можно с оплатой после трудоустройства в Kata Academy.
Узнай подробнее об учебе: https://clck.ru/eBgVD
В Kata можно изучить Java на реальных проектах и задачах за 8 месяцев. Учеба проходит в интенсивном формате под присмотром ментора. В сообществе студентов и выпускников проекта идет непрерывный обмен опытом и знаниями. Выпускники академии получают в среднем от 3 предложений о работе. А если выпускник не находит работу программистом с зарплатой минимум в 100 тысяч рублей, то за обучение он не платит – гарантировано договором.
Начать карьеру востребованного разработчика на Java можно с оплатой после трудоустройства в Kata Academy.
Узнай подробнее об учебе: https://clck.ru/eBgVD
В Kata можно изучить Java на реальных проектах и задачах за 8 месяцев. Учеба проходит в интенсивном формате под присмотром ментора. В сообществе студентов и выпускников проекта идет непрерывный обмен опытом и знаниями. Выпускники академии получают в среднем от 3 предложений о работе. А если выпускник не находит работу программистом с зарплатой минимум в 100 тысяч рублей, то за обучение он не платит – гарантировано договором.
👎8👍3
Как удалить элемент из ArrayList при итерации?
Обычно формулируется в виде задачи на внимательность «что здесь не так», например
Подвох в том, что итератор
Не исключение, но неожиданный результат получится если пользоваться не итератором, а обычным циклом
Единственный способ удалить элемент из коллекции при обходе, не получив при этом
Некоторые коллекции, такие как
#Коллекции
Обычно формулируется в виде задачи на внимательность «что здесь не так», например
for (String item : arrayList)
if (item.length() > 2)
arrayList.remove(item);
Подвох в том, что итератор
ArrayList
, который используется в таком варианте цикла for
, является fail-fast, то есть не поддерживает итерацию с параллельной модификацией. А параллельная модификация случается даже в одном потоке, что демонстрирует этот пример. Следующий шаг итератора после удаления элемента выбросит ConcurrentModificationException
.Не исключение, но неожиданный результат получится если пользоваться не итератором, а обычным циклом
for
– при каждом удалении нумерация элементов будет сдвигаться.Единственный способ удалить элемент из коллекции при обходе, не получив при этом
ConcurrentModificationException
или неопределенное поведение – удалить с помощью remove()
того же инстанса итератора. Вариант ListIterator поможет, если в теле цикла требуется и работа с индексами.Некоторые коллекции, такие как
CopyOnWriteArrayList
и ConcurrentHashMap
адаптированные под многопоточную среду и имеют fail-safe итераторы.#Коллекции
👍14
Forwarded from Академия Кода
Как объединить два массива в один на Java?
Можно использовать метод
пример пример кода.
Подписывайтесь на канал 👉@coddy_academy
#java
Можно использовать метод
arraycopy()
в Java чтобы объединить два массива в один,пример пример кода.
Подписывайтесь на канал 👉@coddy_academy
#java
👍4💩2
Какова структура Java Collections Framework? Почему Map не Collection?
🔘
🔘
🔘
Большой обзор фреймворка и сравнение эффективности коллекций можно найти в статье на хабре. Для разговора об эффективности нужно понимать что такое О-нотация. Другая статья содержит практические замеры быстродействия (осторожно, старая публикация, Java 6).
Collection
– хранилище отдельных значений, Map
– хранилище ключ-значение. Отсюда разные методы этих интерфейсов. Если проще, разные сигнатуры методов put
и add
.Collection
в свою очередь делится на три основных группы, и соответствующих им интерфейса:🔘
List
– упорядоченные списки с возможностью содержания дубликатов и доступа по индексу (random access);🔘
Queue
– обычно FIFO-коллекции, предполагает добавление/удаление элементов с края. Интерфейс-наследник Deque
– двусвязная очередь;🔘
Set
– не обязательно упорядоченный набор уникальных (с точки зрения equals
) значений;HashMap
можно привести к виду Collection
вызвав например keySet()
, entrySet()
или values()
.Большой обзор фреймворка и сравнение эффективности коллекций можно найти в статье на хабре. Для разговора об эффективности нужно понимать что такое О-нотация. Другая статья содержит практические замеры быстродействия (осторожно, старая публикация, Java 6).
👍8
Как работает HashMap?
Один из популярнейших вопросов, потому что содержит много нюансов. Лучше всего подготовиться к нему помогает чтение исходного кода
Нюансы которые стоит повторить и запомнить:
🔘 Общий принцип: внутренний массив
🔘 Пересчет хэш-суммы для умещения
🔘
🔘 Невозможность сжать однажды раздувшийся
🔘 Два способа разрешения коллизий: используемый в
🔘 Варианты для многопоточного использования: пересинхронизированная
🔘 Оптимизация Java 8: превращение списка в бакете в дерево при достижении 8 элементов – при большом количестве коллизий скорость доступа растет с O(n) до O(log(n));
🔘 Явное использование бакета 0 для ключа
🔘 Связь с
🔘 Нет гарантий порядка элементов;
Обсуждая этот вопрос на интервью вы обязательно затронете особенности методов equals/hashCode. Возможно придется поговорить об альтернативных хранилищах ключ-значение – TreeMap, LinkedHashMap.
Один из популярнейших вопросов, потому что содержит много нюансов. Лучше всего подготовиться к нему помогает чтение исходного кода
HashMap
. Реализация подробно рассмотрена во множестве статей, например на хабре.Нюансы которые стоит повторить и запомнить:
🔘 Общий принцип: внутренний массив
table
, содержащий бакеты (корзины) – списки элементов с одинаковыми пересчитанными хэш-суммами;🔘 Пересчет хэш-суммы для умещения
int
индексов в capacity
ячейках table
;🔘
rehash
– удвоение размера table
при достижении threshold
(capacity*loadFactor
) занятых бакетов;🔘 Невозможность сжать однажды раздувшийся
table
;🔘 Два способа разрешения коллизий: используемый в
HashMap
метод цепочек и альтернатива – открытая адресация;🔘 Варианты для многопоточного использования: пересинхронизированная
Hashtable
и умная ConcurrentHashMap
;🔘 Оптимизация Java 8: превращение списка в бакете в дерево при достижении 8 элементов – при большом количестве коллизий скорость доступа растет с O(n) до O(log(n));
🔘 Явное использование бакета 0 для ключа
null
;🔘 Связь с
HashSet
– HashMap
, в котором используются только ключи;🔘 Нет гарантий порядка элементов;
Обсуждая этот вопрос на интервью вы обязательно затронете особенности методов equals/hashCode. Возможно придется поговорить об альтернативных хранилищах ключ-значение – TreeMap, LinkedHashMap.
🔥4👍3
Как отсортировать Set/Map?
Для
Эффективный способ – хранить данные уже отсортированными. Для таких реализаций созданы интерфейсы-наследники
Реализации
Этот интерфейс добавляет методы получения подмножества от указанного элемента (
Все те же правила применяются к элементам
Основными реализациями являются
#Коллекции
Для
Map
можно привести ключи/значения к виду Collection, переложить в новый List
и отсортировать с помощью Collections.sort
. То же делается с Set
. Этот метод конечно же неэффективный, так как потребует полного копирования содержимого.Эффективный способ – хранить данные уже отсортированными. Для таких реализаций созданы интерфейсы-наследники
SortedSet
и SortedMap
.Реализации
SortedSet
дают линейный порядок множества. Элементы упорядочены по возрастанию. Порядок либо натуральный (элементы реализуют интерфейс Comparable
), либо его определяет переданный в конструктор Comparator
.Этот интерфейс добавляет методы получения подмножества от указанного элемента (
tailSet
), до элемента (headSet
), и между двумя (subSet
). Подмножество включает нижнюю границу, не включает верхнюю.SortedSet
расширяется интерфейсом NavigableSet
для итерации по порядку, получения ближайшего снизу (floor
), сверху (ceiling
), большего (higher
) и меньшего (lower
) заданному элемента.Все те же правила применяются к элементам
SortedMap
/NavigableMap
относительно их ключей.Основными реализациями являются
TreeSet
и TreeMap
. Внутри это самобалансирующиеся красно-чёрные деревья. Их структура и способ балансировки – вопрос достойный отдельного поста. Другая любопытная реализация из java.util.concurrent
– ConcurrentSkipListMap. #Коллекции
👍5
Java и вино 🍷 — авторский проект начинающего java-специалиста. Сложный и непростой, но такой интересный путь бывшего маркетолога: с чего начинать, куда податься и как быть, когда ничего не получается.Заметки IT-специалиста о карьере, профессиональной сфере и жизни.
«Вино тут, спросите, зачем в названии? Об этом я тоже постепенно буду рассказывать у себя в блоге»
https://t.me/java_wine
«Вино тут, спросите, зачем в названии? Об этом я тоже постепенно буду рассказывать у себя в блоге»
https://t.me/java_wine
👎4👍3🔥1
Как создать immutable-коллекцию?
В Collections Framework имеется набор методов
Другой менее очевидный способ – метод
#Коллекции
В Collections Framework имеется набор методов
Collections.unmodifiable*()
для различных типов коллекций. Такой метод вернет read-only обертку над переданной коллекцией. Так же как с Collections.synchronized*()
, внутри используется не копия, а оригинальная коллекция.Другой менее очевидный способ – метод
Collections.empty*()
. Он возвращает немодифицируемую пустую коллекцию. Попытка добавить элемент как и в случае unmodifiable приведет к UnsupportedOperationException
.#Коллекции
👍2
Какими коллекциями пользоваться в многопоточной среде?
Первый вариант – превратить в синхронизированную обычную коллекцию, вызвав соответствующий ее типу метод
Если работа с коллекцией состоит в основном из чтения, лучшая в плане производительности альтернатива –
Третий вариант – использование Concurrent-коллекций:
🔘 Неблокирующие хэш-таблицы ConcurrentSkipListMap, ConcurrentHashMap и
🔘 Неблокирующие очереди
🔘 Большой набор различных блокирующих очередей
#Коллекции
#Многопоточность
Первый вариант – превратить в синхронизированную обычную коллекцию, вызвав соответствующий ее типу метод
Collections.synchronized*()
. Самый общий и самый примитивный способ, создает обертку с синхронизацией всех операций с помощью synchronized.Если работа с коллекцией состоит в основном из чтения, лучшая в плане производительности альтернатива –
CopyOnWriteArrayList
, и содержащий его в реализации CopyOnWriteArraySet
. Потокобезопасность достигается копированием внутреннего массива при любой модификации, оригинальный массив остается immutable. Program order достигается модификатором volatile
на внутреннем массиве.Третий вариант – использование Concurrent-коллекций:
🔘 Неблокирующие хэш-таблицы ConcurrentSkipListMap, ConcurrentHashMap и
ConcurrentSkipListSet
(хэш-таблица в основе реализации)🔘 Неблокирующие очереди
ConcurrentLinkedQueue
и ConcurrentLinkedDeque
🔘 Большой набор различных блокирующих очередей
#Коллекции
#Многопоточность
👍9
Какие существуют примитивы?
В Java имеется 9 возможных типов значения переменной: ссылка на объект или один из восьми примитивных типов:
🔘 byte – знаковое целое число от -2^7 до 2^7-1;
🔘 short – знаковое целое число от -2^15 до 2^15-1;
🔘 int – знаковое целое число от -2^31 до 2^31-1;
🔘 long – знаковое целое число от -2^63 до 2^63-1;
🔘 float – знаковое число с плавающей точкой 32 бита стандарта IEEE 754;
🔘 double – то же, что и float, но 64 бита;
🔘 char – 16-битный символ Unicode, от
🔘 boolean –
По умолчанию поля примитивных типов принимают нулевые значения:
Отдельная интересная тема – boxing/unboxing. Каждый примитивный тип снабжен своей ссылочной версией. Примитивное значение заворачивается и разворачивается из него автоматически при необходимости. Это может приводить к большим затратам на выделение памяти, когда например
Сколько памяти занимает примитив – вопрос с подвохом. Спецификация требует, чтобы размер был достаточным для всех значений. Конкретный размер определяется реализацией JVM, он может быть больше. Например в 64-bit HotSpot переменная boolean занимает не 1 бит, а 8.
Для полного погружения рекомендуется подробный официальный туториал по примитивным типам.
#Классы
В Java имеется 9 возможных типов значения переменной: ссылка на объект или один из восьми примитивных типов:
🔘 byte – знаковое целое число от -2^7 до 2^7-1;
🔘 short – знаковое целое число от -2^15 до 2^15-1;
🔘 int – знаковое целое число от -2^31 до 2^31-1;
🔘 long – знаковое целое число от -2^63 до 2^63-1;
🔘 float – знаковое число с плавающей точкой 32 бита стандарта IEEE 754;
🔘 double – то же, что и float, но 64 бита;
🔘 char – 16-битный символ Unicode, от
'\u0000'
(0) до '\uffff'
(65535);🔘 boolean –
true
или false
;По умолчанию поля примитивных типов принимают нулевые значения:
0
, 0L
, '\u0000'
, false
. Про особенности работы, способ хранения и специальные значения чисел с плавающей точкой стоит почитать подробнее.Отдельная интересная тема – boxing/unboxing. Каждый примитивный тип снабжен своей ссылочной версией. Примитивное значение заворачивается и разворачивается из него автоматически при необходимости. Это может приводить к большим затратам на выделение памяти, когда например
int
индекс цикла используется в качестве значения переменной Object
и превращается в Integer
без нужды – частая задача на собеседованиях. Еще классы-обертки содержат набор утилитарных методов для их примитивов.Сколько памяти занимает примитив – вопрос с подвохом. Спецификация требует, чтобы размер был достаточным для всех значений. Конкретный размер определяется реализацией JVM, он может быть больше. Например в 64-bit HotSpot переменная boolean занимает не 1 бит, а 8.
Для полного погружения рекомендуется подробный официальный туториал по примитивным типам.
#Классы
👍9
JPA-Buddy — избавляемся от рутины. Практические кейсы
Совсем недавно мне под руку попался плагин, который помогает генерировать код при написании программ - это JPA Buddy. В этой статье я не буду транслировать официальную документацию проекта или показывать на примере видеороликов, как нужно с ним работать, а приведу примеры своих рабочих кейсов, где плагин действительно выручил и сэкономил мое время. Спойлер: в создании POJO-классов, репозиториев для тучи сущностей, DTO-классов.
https://habr.com/ru/company/reksoft/blog/657379/
Совсем недавно мне под руку попался плагин, который помогает генерировать код при написании программ - это JPA Buddy. В этой статье я не буду транслировать официальную документацию проекта или показывать на примере видеороликов, как нужно с ним работать, а приведу примеры своих рабочих кейсов, где плагин действительно выручил и сэкономил мое время. Спойлер: в создании POJO-классов, репозиториев для тучи сущностей, DTO-классов.
https://habr.com/ru/company/reksoft/blog/657379/
👍3
Не можете продлить нужный сервис, оплатить хостинг или получить деньги из-за рубежа?
Ребята из rk.finaxe.ru тоже столкнулись с данной проблемой и запустили сервис, в котором граждане РФ могут оформить онлайн карту Visa или Mastercard в банке Казахстана.
Для чего это нужно:
— Оплата любых зарубежных сервисов и покупок
— Получение денег из-за рубежа
— Использование в путешествиях
Весь процесс проходит онлайн, от вас потребуется только загранпаспорт, даже вставать с дивана не понадобится!
Оформить заявку и ознакомиться с FAQ можно в боте:
https://t.me/Robokazakh_bot
Ребята из rk.finaxe.ru тоже столкнулись с данной проблемой и запустили сервис, в котором граждане РФ могут оформить онлайн карту Visa или Mastercard в банке Казахстана.
Для чего это нужно:
— Оплата любых зарубежных сервисов и покупок
— Получение денег из-за рубежа
— Использование в путешествиях
Весь процесс проходит онлайн, от вас потребуется только загранпаспорт, даже вставать с дивана не понадобится!
Оформить заявку и ознакомиться с FAQ можно в боте:
https://t.me/Robokazakh_bot
Что такое «анонимные классы»? Где они применяются?
Это вложенный локальный класс без имени, который разрешено декларировать в любом месте обрамляющего класса, разрешающем размещение выражений. Создание экземпляра анонимного класса происходит одновременно с его объявлением. В зависимости от местоположения анонимный класс ведет себя как статический либо как нестатический вложенный класс - в нестатическом контексте появляется окружающий его экземпляр.
Анонимные классы имеют несколько ограничений:
• Их использование разрешено только в одном месте программы - месте его создания;
• Применение возможно только в том случае, если после порождения экземпляра нет необходимости на него ссылаться;
• Реализует лишь методы своего интерфейса или суперкласса, т.е. не может объявлять каких-либо новых методов, так как для доступа к ним нет поименованного типа.
Анонимные классы обычно применяются для:
• создания объекта функции (function object), например, реализация интерфейса
• создания объекта процесса (process object), такого как экземпляры классов
• в статическом методе генерации;
• инициализации открытого статического поля
Это вложенный локальный класс без имени, который разрешено декларировать в любом месте обрамляющего класса, разрешающем размещение выражений. Создание экземпляра анонимного класса происходит одновременно с его объявлением. В зависимости от местоположения анонимный класс ведет себя как статический либо как нестатический вложенный класс - в нестатическом контексте появляется окружающий его экземпляр.
Анонимные классы имеют несколько ограничений:
• Их использование разрешено только в одном месте программы - месте его создания;
• Применение возможно только в том случае, если после порождения экземпляра нет необходимости на него ссылаться;
• Реализует лишь методы своего интерфейса или суперкласса, т.е. не может объявлять каких-либо новых методов, так как для доступа к ним нет поименованного типа.
Анонимные классы обычно применяются для:
• создания объекта функции (function object), например, реализация интерфейса
Comparator
;• создания объекта процесса (process object), такого как экземпляры классов
Thread
, Runnable
и подобных;• в статическом методе генерации;
• инициализации открытого статического поля
final
, которое соответствует сложному перечислению типов, когда для каждого экземпляра в перечислении требуется отдельный подкласс.👍6