Вопросы для интервью -- коллекция java

интервью

Вопросы для интервью -- коллекция java

Введение

Контейнер может управлять жизненным циклом объектов и зависимостями между объектами.Вы можете использовать файл конфигурации (обычно XML), чтобы определить имя объекта и способ его создания (прототип). способ или синглтон метод), какой объект должен быть установлен в качестве атрибута объекта после его генерации и т. д. После запуска контейнера ко всем объектам можно получить прямой доступ без написания какой-либо строки программного кода для генерации объектов или установления связи между объектами. и объекты зависимости.
Контейнер — это программа, написанная на Java.Первоначально вам нужно было написать собственную программу для управления отношениями между объектами, но теперь контейнер сделает это за вас автоматически.

在这里插入图片描述
Классы-коллекции хранятся в пакете Java.util и бывают трех основных типов: set (набор), list (список содержит Queue) и map (карта).

1.Collection:

  • Коллекция — это самый простой интерфейс коллекции List, Set, Queue.
  • Коллекция — это самый простой интерфейс коллекции.Коллекция представляет собой группу объектов, то есть элементов коллекции. Некоторые коллекции допускают одни и те же элементы, а другие — нет, некоторые — нет. Java SDK не предоставляет классы, которые напрямую наследуются от Collection.Классами, предоставляемыми Java SDK, являются все «вложенные интерфейсы», которые наследуются от Collection, такие как List и Set.
  • Все классы, реализующие интерфейс Collection, должны предоставлять два стандартных конструктора: конструктор без параметров используется для создания пустой Collection; конструктор с параметром Collection используется для создания новой Collection, новой Collection и переданной. элементы. Последний конструктор позволяет пользователю копировать коллекцию.
  • (1) Список: упорядоченный, может хранить повторяющийся контент
  • (2) Установить: неупорядоченный и не может хранить повторяющийся контент, поэтому повторяющийся контент распознается методами hashCode() и equals().
  • (3) Очередь: интерфейс очереди
  • (4) SortedSet: вы можете сортировать данные в наборе

Коллекция — это интерфейс верхнего уровня в структуре коллекций, который определяет общие методы для коллекций с одним столбцом.

Он имеет два часто используемых субинтерфейса:

  • Список: Все элементы имеют определенные индексы. Заказал. Элементы могут повторяться.
  • Set: Элементы не могут повторяться. не работает.

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

2.Iterator:

  • Итератор, вы можете просматривать данные в коллекции через итератор
  • (Интерфейс итератора) Интерфейс, используемый для обхода элементов в коллекции, в основном включающий три метода:
    boolean hasNext()
    E next()
    void remove()
  • Один из его подинтерфейсов, ListIterator, добавляет к нему еще три метода:
    void add()
    E previous()
    boolean hasPrevious()

Разница между итератором и итерируемым:

  • 1) Iterator — это интерфейс итератора, а Iterable должен использовать foreach для итерации до тех пор, пока интерфейс реализован.
  • 2) Интерфейс Iterator инкапсулирован в Iterable. Пока класс, который реализует интерфейс Iterable, можно использовать итератор Iterator.
  • 3) Коллекции Collection, List и Set являются классами реализации Iterable, поэтому они и их подклассы могут использовать foreach для итерации.
  • 4). Основные методы next(), hasnext() и remove() в Iterator зависят от текущей позиции. Если эти коллекции непосредственно реализуют Iterator, они должны включать указатель на текущую позицию итерации. Когда коллекция передается между методами, поскольку текущая позиция неизвестна, значение после next() также неизвестно. В реализации Iterable дело обстоит иначе: каждый вызов возвращает итератор с нуля, и каждый итератор не влияет друг на друга.

3.Map: это основа таблицы отображения

Карта — это контейнер, который связывает ключевые объекты с объектами-значениями, а объект-значение может быть Картой и т. д., чтобы можно было сформировать многоуровневую карту. Для ключевых объектов, таких как Set, ключевые объекты в контейнере Map не могут повторяться, это необходимо для обеспечения согласованности результатов поиска; если есть два одинаковых ключевых объекта, вы хотите получить объект значения, соответствующий к этому ключевому объекту. Когда возникает проблема, вы можете не получить объект значения, который вы думаете, и результат вызовет путаницу, поэтому уникальность ключа очень важна, и она также соответствует характеру набора. Конечно, в процессе использования объект-значение, соответствующий ключу, может измениться, и тогда объект-значение, соответствующий ключу, будет соответствовать последнему измененному значению. Для объектов-значений нет уникальных требований. Вы можете без проблем сопоставить любое количество ключей с объектом значения (хотя это может быть неудобно для вашего использования, вы не знаете, какой объект значения вы получаете для какого ключа).
Обратите внимание, что Map не наследует интерфейс Collection, а Map обеспечивает сопоставление ключа со значением. Карта не может содержать один и тот же ключ, и каждый ключ может отображать только одно значение. Интерфейс карты предоставляет три набора представлений.Содержимое карты можно рассматривать как набор наборов ключей, набор наборов значений или набор сопоставлений ключ-значение.

在这里插入图片描述

List:

Список Java — очень распространенный тип данных.Список представляет собой упорядоченную коллекцию. Java List имеет три класса реализации:ArrayList, Vector и LinkedList соответственно.

  1. ArrayList (массив)ArrayList — это наиболее часто используемый класс реализации List, который внутренне реализован с помощьюмножествореализован, он обеспечивает быстрый произвольный доступ к элементам. массивНедостатком является то, что между каждым элементом не может быть места., когда размер массива не устраивает, необходимо увеличить емкость хранилища и скопировать данные существующего массива в новое пространство для хранения. При вставке или удалении элементов из середины ArrayList массив необходимо копировать, перемещать и дорого. Поэтому подходитСлучайный поиск и обход, не подходит для вставки и удаления.
  2. Вектор (реализация массива, синхронизация потоков)Vector, как и ArrayList, также проходитмножествоОтличие в том, что он поддерживает синхронизацию потоков, то есть только один поток может записывать Vector в определенное время, избегая несогласованности, вызванной многопоточной записью одновременно, но реализация синхронизации требует больших затрат. это лучше, чем доступ к ArrayList.
  3. .LinkList (связанный список)LinkedList использует структуру связанного списка для хранения данных, что очень удобно для динамической вставки и удаления данных, а скорость произвольного доступа и обхода относительно низкая. Кроме того, он также предоставляет методы, не определенные в интерфейсе List, которые специально используются для работы с элементами верхнего и нижнего колонтитула, которые можно использовать в качестве стеков, очередей и двунаправленных очередей.

Set

Set обращает внимание на уникальные свойства.Системный набор используется для хранения неупорядоченных (порядок хранения и извлечения не обязательно одинаков) элементов, значения которых не могут повторяться. Суть равенства объектов заключается в значении хэш-кода объекта (java основана на объектномадрес памятиВычисленный серийный номер), если вы хотите, чтобы два разных объекта считались равными, вы должны переопределитьМетод объекта hashCode и метод equals.

  1. HashSet (хеш-таблица)
    Сторона хеш-таблицы хранит значение хеш-функции. Порядок элементов хранения HashSet не в соответствии с порядком хранения (очевидно, отличается от List), а в соответствии с хеш-значением, поэтому данные также получаются в соответствии с хеш-значением. Хэш-значение элемента получается с помощью метода хэш-кода элемента. HashSet сначала оценивает хеш-значение двух элементов. Если хеш-значение одинаковое, сравнивается метод equals. Если результат equls истинен, HashSet считается одним и тем же элементом. Если equals ложно, то это не один и тот же элемент.
    Как хранить элементы с одинаковым хеш-значением и равными как false, то есть они расширяются под одним и тем же хеш-значением (можно считать, что элементы с одинаковым хеш-значением помещаются в хэш-баг). То есть столбец хранится как хэш. На рисунке 1 показан случай, когда значения hashCode не совпадают, на рисунке 2 показан случай, когда значения hashCode одинаковы, но равенства не совпадают.
    HashSet использует значение hashCode для определения местоположения элемента в памяти. Несколько элементов могут быть сохранены в расположении hashCode.

  2. TreeSet (бинарное дерево)
    TreeSet() использует принцип бинарного дерева для сортировки объектов нового add() в указанном порядке (по возрастанию, по убыванию).Каждый раз, когда объект добавляется, он будет сортироваться, и объект будет вставлен в указанную позицию бинарного дерева. Объекты Integer и String могут быть отсортированы по умолчанию TreeSet, но объекты пользовательских классов не допускаются.Класс, определенный вами, должен реализовать интерфейс Comparable и переопределить соответствующую функцию compareTo(), прежде чем его можно будет использовать в обычном режиме.
    При переопределении функции compare() должно быть возвращено соответствующее значение, чтобы TreeSet можно было отсортировать по определенным правилам.
    Порядок, в котором этот объект сравнивается с указанным объектом. Если объект меньше, равен или больше указанного объекта, возвращает отрицательное целое число, ноль или положительное целое число соответственно.

  3. LinkHashSet (HashSet+LinkedHashMap)
    Для LinkedHashSet он наследуется от HashSet и реализован на основе LinkedHashMap. Нижний слой LinkedHashSet использует LinkedHashMap для сохранения всех элементов, он наследуется от HashSet, и все его методы и операции такие же, как у HashSet, поэтому реализация LinkedHashSet очень проста, предусмотрено всего четыре метода построения, а родителем является вызывается путем передачи параметра идентификации.Конструктор класса, нижний слой строит LinkedHashMap для реализации, операция такая же, как операция родительского класса HashSet, вы можете напрямую вызвать метод родительского класса HashSet.

Map

  1. HashMap (массив + связанный список + красно-черное дерево) не является потокобезопасным
    HashMap хранит данные по значению hashCode ключа, в большинстве случаев его значение можно найти напрямую, поэтому у него высокая скорость доступа, но порядок обхода не определен. HashMap позволяет ключу не более чем одной записи быть нулевым, а значение нескольких записей может быть нулевым.
    HashMap не является потокобезопасным, то есть несколько потоков могут одновременно записывать HashMap в любое время, что может привести к несогласованности данных. Если вам необходимо обеспечить безопасность потоков, вы можете использовать метод synchronizedMap Collections, чтобы сделать HashMap потокобезопасным, или использовать ConcurrentHashMap. Мы используем следующую картинку, чтобы представить структуру HashMap.

Реализация java7:

在这里插入图片描述

В HashMap есть массив, и каждый элемент массива представляет собой односвязный список. На приведенном выше рисунке каждая зеленая сущность является экземпляром вложенного класса Entry. Entry содержит четыре свойства: ключ, значение, хэш-значение и следующий для односвязного списка.

  • емкость: Текущая емкость массива, которая всегда поддерживается на уровне 2^n, может быть увеличена.После расширения размер массива будет в два раза больше текущего размера.
  • loadFactor: коэффициент нагрузки, по умолчанию 0,75.
  • Размер по умолчанию 16.
  • порог: Порог для расширения, равный емкости * loadFactor (Расширять, когда длина массива достигает 12 (16*0,75))

Реализация JAVA8
Java8 внесла некоторые изменения в HashMap, самая большая разница заключается в использовании красно-черного дерева, поэтому оно состоит из массива + связанный список + красно-черное дерево.
Согласно представлению Java7 HashMap, мы знаем, что при поиске мы можем быстро найти конкретный индекс массива в соответствии с хеш-значением, но после этого нам нужно сравнить связанный список один за другим, чтобы найти то, что нам нужно. Временная сложность зависит от длины связанного списка O (n). Чтобы уменьшить накладные расходы этой части, в Java8, когда количество элементов в связанном списке превышает 8, связанный список будет преобразован в красно-черное дерево, а временная сложность может быть уменьшена до O (logN) при поиске по этим позициям.

在这里插入图片描述
HashMap небезопасен для потоков, и его основными проявлениями являются:

  • В jdk1.7 в многопоточной среде при увеличении емкости возникает кольцевая цепочка или потеря данных.

  • В jdk1.8 в многопоточной среде будет происходить покрытие данных.

В разработке мы часто используем контейнер HashMap для хранения пар ключ-значение KV, но в случае параллельной многопоточности контейнер HashMap небезопасен, так как при помещении элемента, если срабатывает операция раскрытия, т.е. rehash, это будет Содержимое исходного массива будет повторно хэшировано в новый массив расширения, но в процессе расширения другие потоки также выполняют операции ввода.Если значения хеш-функции этих двух элементов совпадают, они могут быть представлены связанным списком в одном и том же массиве в одно и то же время.Вызывает замкнутый цикл, приводящий к бесконечному циклу при получении, поэтому HashMap небезопасен для потоков.

  1. ConcurrentHashMap
    Сегмент
    ConcurrentHashMap и HashMap имеют схожие идеи, но поскольку они поддерживают параллельные операции, они сложнее. Весь ConcurrentHashMap состоит из сегментов, а «сегмент» означает «часть» или «сегмент», поэтому во многих местах он описывается как блокировка сегмента. Обратите внимание, что в тексте я использую «слот» во многих местах для обозначения сегмента.потокобезопасность(Сегмент наследует ReentrantLock для блокировки)
    Простое понимание состоит в том, что ConcurrentHashMap — это массив сегментов, а сегменты заблокированы путем наследования ReentrantLock, поэтому каждая операция, которую необходимо заблокировать, блокирует сегмент, поэтому, пока каждый сегмент гарантированно является потокобезопасным, глобальная потокобезопасность .
    在这里插入图片描述
    Степень параллелизма (по умолчанию 16)
    concurrencyLevel: уровень параллелизма, concurrency, номер сегмента, как перевести не важно, разбирайтесь. Значение по умолчанию — 16, что означает, что ConcurrentHashMap имеет 16 сегментов, поэтому теоретически в настоящее время одновременно могут писать до 16 потоков, если их операции распределены по разным сегментам. Этому значению можно присвоить другие значения во время инициализации, но после инициализации его нельзя расширить. Чтобы быть конкретным внутри каждого сегмента, на самом деле каждый сегмент очень похож на HashMap, представленный ранее, но он должен обеспечивать безопасность потоков, поэтому его сложнее обрабатывать.

Реализация Java8 (представлено красно-черное дерево)
Java8 внесла серьезные изменения в ConcurrentHashMap, а Java8 также представила красно-черные деревья.

在这里插入图片描述
ConcurrentHashMap в 1.8 отказывается от технологии сегментации в JDK1.7, но принимает механизм CAS + синхронизированный для обеспечения безопасности параллелизма, но сохраняет определение сегмента в реализации ConcurrentHashMap, которое предназначено только для обеспечения совместимости во время сериализации. не имеют никакой структурной полезности.

  1. HashTable (потокобезопасный) неэффективен

Hashtable — это устаревший класс. Общие функции многих отображений аналогичны HashMap. Разница в том, что он наследуется от класса Dictionary и является потокобезопасным. Только один поток может писать Hashtable в любой момент времени. Параллелизм не так хорош, как у ConcurrentHashMap. , потому что ConcurrentHashMap вводит блокировку сегментации. Hashtable не рекомендуется использовать в новом коде, его можно заменить HashMap, когда не требуется потокобезопасность, и ConcurrentHashMap, когда требуется потокобезопасность.
Hashtable - это добавление "" для размещения, получения, размера и других методов.synchronized«Блокировки используются для обеспечения безопасности, что приводит к тому, что все параллельные операции конкурируют за одну и ту же блокировку. Когда один поток выполняет синхронную операцию, другие потоки могут только ждать, что значительно снижает эффективность параллельных операций.

  1. TreeMap (сортируемый)

TreeMap реализует интерфейс SortedMap, который может сортировать записи, которые он сохраняет, в соответствии с ключами. По умолчанию используется сортировка в порядке возрастания значений ключей. Вы также можете указать компаратор сортировки. Когда итератор используется для обхода TreeMap, полученный записи сортируются.
Если вы используете отсортированные карты, рекомендуется использовать TreeMap.
При использовании TreeMap ключ должен реализовывать интерфейс Comparable или передавать пользовательский компаратор при построении TreeMap, иначе во время выполнения будет создано исключение типа java.lang.ClassCastException.

  1. LinkHashMap (запись порядка вставки)

LinkedHashMap — это подкласс HashMap, который сохраняет порядок вставки записей.При использовании Iterator для обхода LinkedHashMap первая запись должна быть вставлена ​​первой, либо она может быть построена с параметрами и отсортирована в соответствии с порядком доступа.

============== END ==============