Сообщения

Когда использовать ArrayList, а когда LinkedList

Изображение
ArrayList с ArrayDeque предпочтительнее во многих других случаях использования, чем LinkedList. Если вы не уверены - начните с ArrayList. В ArrayList доступ к элементу занимает линейное время, а добавление элемента занимает время O(n) (худший случай). В LinkedList добавление элемента занимает O(n) времени, а доступ также занимает O(n) времени, но LinkedList использует больше памяти, чем ArrayList. LinkedList и ArrayList - две разные реализации интерфейса List. LinkedList реализует его с помощью двусвязного списка. ArrayList реализует его с помощью массива динамического изменения размера. Как и в случае стандартных операций со связанными списками и массивами, различные методы будут иметь разное время выполнения алгоритмов. Для LinkedList<E> get(int index) равно O(n) (в среднем n/4 шагов), но O(1), когда index = 0 или index = list.size() - 1 (в этом случае вы также можете использовать getFirst() и getLast()). Одно из основных преимуществ LinkedList<E> add(int index, E

Интерфейс Collection: коллекции представлений, неизменяемые коллекции

Изображение
Коллекции представлений Большинство коллекций управляют хранением содержащихся в них элементов. Напротив, коллекции представлений (view collections) сами по себе не хранят элементы, а вместо этого полагаются на вспомогательную коллекцию для хранения фактических элементов. Операции, которые не обрабатываются самой коллекцией представлений, делегируются вспомогательной коллекции. Примеры коллекций представлений включают коллекции оболочек, возвращаемые такими методами, как Collections.checkedCollection, Collections.synchronizedCollection и Collections.unmodifiableCollection. Другие примеры коллекций представлений включают коллекции, которые обеспечивают другое представление одних и тех же элементов, например, предоставляемое List.subList, NavigableSet.subSet или Map.entrySet. Любые изменения, внесенные в вспомогательную коллекцию, отображаются в коллекции представлений. Соответственно, любые изменения, внесенные в коллекцию представлений - если изменения разрешены - записываются в вспом

Интерфейс Collection в Java

Изображение
Корневой интерфейс в иерархии коллекции. Коллекция представляет собой группу объектов, называемых ее элементами. Некоторые коллекции позволяют дублировать элементы, а другие нет. Некоторые упорядочены, а другие нет. JDK не предоставляет прямых реализаций этого интерфейса: он предоставляет реализации более конкретных подинтерфейсов, таких как Set и List. Этот интерфейс обычно используется для передачи коллекций и управления ими там, где требуется максимальная универсальность. Пакеты или мультимножества (неупорядоченные коллекции, которые могут содержать повторяющиеся элементы) должны реализовывать этот интерфейс напрямую. Все универсальные классы реализации Collection (которые обычно реализуют Collection косвенно через один из ее подинтерфейсов) должны предоставлять два «стандартных» конструктора: конструктор void (без аргументов), который создает пустую коллекцию, и конструктор с одним аргументом типа Collection, которая создает новую коллекцию с теми же элементами, что и ее аргумент.

Спецификация Java 11: 17.7. Неатомарная обработка double и long

Изображение
В рамках модели памяти языка программирования Java одна запись в не-volatile long или double значение рассматривается как две отдельные записи: по одной в каждую 32-битную половину. Это может привести к ситуации, когда поток видит первые 32 бита 64-битного значения при одной записи, а вторые 32 бита - при другой записи. Запись и чтение volatile long и double значений всегда атомарны. Запись и чтение ссылок всегда атомарны, независимо от того, реализованы ли они как 32-битные или 64-битные значения. В некоторых реализациях может оказаться удобным разделить одно действие записи для 64-битного long или double значения на два действия записи для смежных 32-битных значений. Для повышения эффективности это поведение зависит от реализации; реализация виртуальной машины Java может выполнять запись в long и double значения атомарно или в двух частях. Реализациям виртуальной машины Java рекомендуется избегать разделения 64-битных значений, где это возможно. Программистам рекомендуется объявл

Спецификация Java 11: 17.6. Разрыв слова

Изображение
Одним из соображений при реализации виртуальной машины Java является то, что каждое поле и элемент массива считаются отдельными; обновления одного поля или элемента не должны взаимодействовать с чтениями или обновлениями любого другого поля или элемента. В частности, два потока, которые обновляют смежные элементы массива байтов по отдельности, не должны мешать или взаимодействовать и не нуждаются в синхронизации для обеспечения последовательной согласованности. Некоторые процессоры не предоставляют возможность записи в один байт. Было бы незаконно реализовывать обновления массива байтов на таком процессоре, просто считывая все слово, обновляя соответствующий байт, а затем записывая все слово обратно в память. Эта проблема иногда известна как разрыв слова (word tearing), и на процессорах, которые не могут легко обновить отдельный байт, потребуется другой подход. Пример - обнаружение разрыва слов Следующая программа представляет собой тестовый пример для обнаружения разрывов слов:

Спецификация Java 11: 17.5. Чтение, изменение final полей

Изображение
17.5.1. Семантика final полей Пусть o будет объектом, а c будет конструктором для o, в котором записано final поле f. Замораживание (freeze action) последнего поля f из o происходит, когда c выходит, как обычно, так и внезапно. Обратите внимание, что если один конструктор вызывает другой конструктор, а вызываемый конструктор устанавливает final поле, замораживание final поля происходит в конце вызываемого конструктора. Для каждого выполнения на поведение чтения влияют два дополнительных частичных порядка: цепочка разыменования dereferences() и цепочка памяти (memory chain) mc(), которые считаются частью выполнения (и, таким образом, фиксируются для любого конкретного выполнения). Эти частичные порядки должны удовлетворять следующим ограничениям (которые не обязательно должны иметь уникальное решение): Цепочка разыменования: если действие a является чтением или записью поля или элемента объекта o потоком t, который не инициализировал o, то должно существовать некоторое чтение r пот

Спецификация Java 11: 17.5. Семантика final полей

Изображение
Поля, объявленные final, инициализируются один раз, но никогда не изменяются при нормальных обстоятельствах. Подробная семантика final полей несколько отличается от семантики обычных полей. В частности, компиляторы могут свободно перемещать операции чтения полей final через барьеры синхронизации и вызовы произвольных или неизвестных методов. Соответственно, компиляторам разрешено сохранять значение конечного поля в кэше в регистре и не перезагружать его из памяти в ситуациях, когда необходимо перезагрузить не-final поле. Поля final также позволяют программистам реализовать потокобезопасные неизменяемые объекты без синхронизации. Поточно-безопасный неизменяемый объект рассматривается как неизменный для всех потоков, даже если для передачи ссылок на неизменяемый объект между потоками используется гонка данных. Это может обеспечить гарантии безопасности от неправильного использования неизменяемого класса неправильным или вредоносным кодом. Поля final должны использоваться правильно, чтоб