После прочтения этого ArrayList зарплата сразу +1000

Java задняя часть

Это 19-й день, когда я участвую в Gengwen Challenge, проверьте подробности мероприятия:Обновить вызов

Добавить Автора

Публичный аккаунт WeChat: разработка Java ноль к одному

предисловие

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

текст

Dog Leftovers: Flower Gie, новая серия открыта, я все еще немного взволнован!

Ведь несколько серий одновременно - это немного опасно для жизни.Посмотрите на мою макушку, которая день ото дня светлеет, эй, я молчу.

Dog Leftovers: ....Я сберегу вам шампунь в будущем, а вы будете нести чушь.Подскажите, на какие моменты мне следует обратить внимание при изучении и сборе!

(задумчиво дотронулся до гладкой макушки) Что касается коллекции, то я думаю, что основными моментами для беспокойства являются:Следующие четыре пункта:

  • Разрешить ли пустое
  • Разрешить ли дублирование данных
  • Является ли порядок упорядоченным, порядок означает, совпадает ли порядок чтения данных с порядком, в котором данные хранятся.
  • Это потокобезопасно?

Dog Leftovers: Можете ли вы рассказать мне, как используется ArrayList?

Сначала посмотрите на его метод добавления элементовadd(), очень просто, код такой:

List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);

Dog Leftovers: Выглядит очень просто, поговорим о том, как новое дополнение реализовано внизу!

....Что так внезапно?Прямо в точку,ладно,приходи-приходи

Взгляните на исходный код метода add:

image.png

Метод sureCapacity в строке 2 предназначен для расширения емкости, поэтому какое-то время не смотрите на него. Нижний слой на самом деле просто добавляет часть данных в определенную позицию elementData при вызове метода добавления, что представлено вот такой картинкой:

图片

Здесь необходимо напомнить, что элементы, хранящиеся в elementData, должны быть элементами в памяти кучи.Цитировать, а не фактические элементы, рисунок Хуа Ге в основном для понимания друзей, если вы знаете эту проблему.

Dog Leftovers: Каков принцип метода расширения вsureCapacity?

Йо-хо, сегодня Гоузи стал интервьюером, и он знает, как задавать вопросы. Давайте сначала посмотрим.При построении ArrayList размер базового массива по умолчанию равен 10:

image.png

Поскольку размер фиксирован, что делать, если размера базового массива недостаточно? Все собаки знают, что это расширение, поэтому всегда говорят, что нижний слой ArrayList основан надинамический массивПричина реализации, динамический массив означает, что размер базового массива не является фиксированным, а решение принимается в соответствии с размером добавленного элемента.Если этого недостаточно, он будет динамически расширяться.Код расширения в обеспечении емкости:

 private void grow(int minCapacity) {
     //1. 获取数组长度
     int oldCapacity = elementData.length;
     
     //oldCapacity >> 1 相当于除以2
     //2. 新数组容量=原数组容量 * 1.5。
     int newCapacity = oldCapacity + (oldCapacity >> 1);
     
     //3. 如果新的数组容量小于传入的参数要求的最小容量minCapacity,那么新的数组容量以传入的容量参数为准。
     if (newCapacity - minCapacity < 0)
         newCapacity = minCapacity;
     
     //4. 判断新的数组容量newCapacity是否大于数组能容纳的最大元素个数 MAX_ARRAY_SIZE
     if (newCapacity - MAX_ARRAY_SIZE > 0)
         //5.
         newCapacity = hugeCapacity(minCapacity);
     
     //6. 将扩容前数组放进新的扩容后的数组
     elementData = Arrays.copyOf(elementData, newCapacity);
 }

где шаг 5hugeCapacity(minCapacity)Используется для оценки входящих параметровminCapacityЭто больше, чемMAX_ARRAY_SIZE,еслиminCapacityбольше, чемMAX_ARRAY_SIZE,ТакnewCapacityравныйInteger.MAX_VALUE, в противном случаеnewCapacityравныйMAX_ARRAY_SIZE

private static int hugeCapacity(int minCapacity) {
    if (minCapacity < 0) // overflow
        throw new OutOfMemoryError();
    return (minCapacity > MAX_ARRAY_SIZE) ?
        Integer.MAX_VALUE :
    MAX_ARRAY_SIZE;
}

Dog Leftovers: кажется, что это очень простой способ расширения, так зачем использовать этот метод для расширения?

Начальство решило, я могу ответить, как расширить мощности не хватает, и почему, зачем вам 100000.

Остатки собак: Если ответ правильный, зарплата будет увеличена на 500.

Вот так, все в порядке.

image.png

Мы можем думать о:

1. Если одноразовое расширение слишком велико, это неизбежно приведет к пустой трате памяти.

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

Таким образом, объем расширения является компромиссом, сделанным разработчиками JDK с точки зрения времени и пространства, и предоставляется более разумная стоимость. Наконец, метод copyOf Arrays вызывается для копирования содержимого группы элементов в новый массив:

image.png

Это представлено диаграммой:

图片

Dog Leftovers: Тот, что со значком, отличный. Я дам вам один. Помимо добавления элементов по порядку, должны быть некоторые вставленные по подстрочному индексу.

Вы действительно умны, операция вставки ArrayList также вызывает метод добавления, например:

List<String> list = new ArrayList<>();
list.add("111");
list.add("222");
list.add("333");
list.add("444");
list.add("555");
list.add("666");
list.add("777");
list.add("888");
list.add(2,"000");
System.out.println(list);

Не ошибитесь, метод add в строке 10 означает вставку данных в первый нижний индекс, например, строка 10 предназначена для вставки данных 000 в позицию нижнего индекса 2 (обратите внимание, что нижний индекс ArrayList начинается с 0, что то есть значение list.get(0) равно 111). Взгляд на беговые результаты также доказывает это:

[111, 222, 000, 333, 444, 555, 666, 777, 888]

Или посмотрите, что делается при вставке:

image.png

Вы можете видеть, что при вставке сначала используйте метод sureCapacity, чтобы определить, следует ли расширять в соответствии с указанной позицией, а затем используйте метод System.arraycopy, чтобы сделать полную копию всех элементов, начиная с указанной позиции, переместиться на одну позицию назад , а затем укажите элемент в позиции. Установите элемент, который необходимо вставить, и операция вставки будет завершена. Графически процесс изображается так:

图片

Dog Leftovers: Yo~ Неплохо, давайте поговорим об удалении элементов!

ArrayList поддерживает следующие два метода удаления:

  • Удалить по индексу, т.е. list.remove(1)

  • Удалить в соответствии с элементом, метод использования list.remove("111"), если есть несколько элементов с одинаковым значением111, также просто удаляет первый элемент, который соответствует

С точки зрения кода принципы реализации этих двух методов удаления в ArrayList схожи, и вызывается следующий код:

image.png

Короче говоря, есть только две вещи, которые нужно сделать:

  1. Используйте метод System.arraycopy, чтобы переместить все элементы позади указанного элемента на одну позицию целиком.

  2. Элемент в последней позиции указывается как null, чтобы gc мог его переработать.

Например, теперь задействуйте этот фрагмент кода:

List<String> list = new ArrayList<>();
list.add("111");
list.add("222");
list.add("333");
list.add("444");
list.add("555");
list.add("666");
list.add("777");
list.add("888");
list.remove("3333");

Он представлен графически как:

图片

Dog Leftovers: Затем вы суммируете характеристики ArrayList!

ArrayList должен быть классом коллекции, который очень часто используется новичками для больших боссов.Реализован как массивКоллекция цветов, Ги использует таблицу, чтобы сначала посмотреть на основные элементы в ArrayList:

элемент роль
private transient Object[] elementData; ArrayList — это реализация, основанная на массивах, а elementData — это базовый массив.
private int size; Количество элементов в ArrayList, здесь следует отметить, что размер увеличивается или уменьшается в соответствии с количеством вызовов методов добавления и удаления, поэтому, если в ArrayList добавить нуль, размер также увеличится на 1

Список свойств ArrayList:

Атрибуты в заключении
Разрешает ли ArrayList null позволять
Позволяет ли ArrayList дублировать данные позволять
Является ли ArrayList упорядоченным? аккуратный
Является ли ArrayList потокобезопасным Не потокобезопасный

Dog Leftovers: Каковы преимущества и недостатки ArrayList?

Ничто не идеально, мы должны разумно использовать его в сочетании со сценой, преимущества ArrayList заключаются в следующем:

  1. Нижний слой ArrayList реализован в виде массива, который является своего родапроизвольный доступрежиме, а также реализует интерфейс RandomAccess, поэтому поиск выполняется очень быстро при получении
  2. ArrayList очень удобен при добавлении элемента последовательно, просто добавляя элемент в массив

Но ArrayListнедостатокТоже очень очевидно:

  1. При удалении элемента задействуется копия элемента, если копировать много элементов, это потребляет больше производительности.

  2. При вставке элемента задействована копия элемента.Если копируемых элементов много, это потребляет больше производительности.

Итак, краткое содержание такое:ArrayList больше подходит для сценариев последовательного добавления и произвольного доступа..

Расширенный раздел

Dog Leftovers: Меня давно мучает вопрос: почему elementData массива List модифицируется транзиентом?

image.png

Это почти за гранью моего познания, но, к счастью, Ги провел прошлую ночь за чтением книги читов.

image.png

Давайте посмотрим на определение ArrayList:

image.png

ArrayList реализует интерфейс Serializable, что означает, что ArrayList может быть сериализован, а изменение elementData с помощью переходного процесса означает, что я не хочу сериализовать массив elementData.

Эти 10 000 грязно-травяных лошадей скачут мимо, ты не можешь паниковать? Потому что при сериализации ArrayList elementData может быть не полным, например, elementData имеет размер 10, а я использую только 3 из них, значит нужно сериализовать весь elementData? Очевидно, в этом нет необходимости, поэтому метод writeObject переопределяется в ArrayList:

image.png

Вызывайте этот метод каждый раз при сериализации, первый вызовdefaultWriteObject()Метод сериализует непереходные элементы в ArrayList, elementData не сериализует его, а затем проходит через elementData, сериализуя только те элементы, что будет иметь два преимущества:

  1. Ускорить сериализацию

  2. Уменьшен размер файла после сериализации

Суммировать

Каждый должен знать о важности ArrayList, поэтому я не буду здесь многословен. Когда мы читаем исходный код, на самом деле есть много вещей, которые мы можем узнать. Например, elementData использует переходные процессы для украшения. Нам нужно больше думать во время обучения и применять изученные технологии и идеи в нашей реальной разработке. Только применяя что мы узнали, мы можем стать сильнее.

Будьте внимательны, чтобы не потерять

Выше приведено все содержание этого вопроса,Если есть какие-либо ошибки, пожалуйста, оставьте сообщение для совета, большое спасибо. Я GieGie. Если у вас есть какие-либо вопросы, не стесняйтесь оставлять сообщение для обсуждения. До встречи в следующем выпуске 🦮.

+++

Статья постоянно обновляется, вы можете искать в WeChatРазработка на Java ноль к одномуПрочтите это в первый раз и получите егоУчебное видео по материалам интервьюПодождите, заинтересованные друзья могут обратить внимание, учиться вместе и работать вместе 🐮🥃.

Оригинальность непроста, как можно терпеть проститутку даром?, если вы считаете, что эта статья вам полезна, спасибо старому железяку за эту статью点个赞、评论或转发一下, потому что это будет моей мотивацией выводить больше качественных статей, спасибо!