Многие объяснения уже присутствуют, чтобы объяснить, как это происходит и как это исправить, но вы также должны следовать рекомендациям, чтобы избежать NullPointerException
вообще.
См. также: A хороший список лучших практик
Я бы добавил, очень важно, хорошо использовать модификатор final
. Использование "окончательной" модификатор, когда это применимо в Java
Сводка:
final
для обеспечения хорошей инициализации. @NotNull
и @Nullable
if("knownObject".equals(unknownObject)
valueOf()
поверх toString (). StringUtils
StringUtils.isEmpty(null)
. Посмотрите на дженерик List<T>
как замена для массивов. Они поддерживают большинство массивов того же самого, делают, включая выделение размера исходной системы хранения, если Вы хотите.
Лучшая вещь, которую можно сделать, состоит в том, чтобы выделить столько памяти, сколько Вам нужно заранее, если это возможно. Это предотвратит .NET от необходимости выполнить дополнительные вызовы для получения памяти на "куче". При сбое этого тогда, которое имеет смысл выделять в блоках пять или независимо от того, что число имеет смысл для приложения.
Это - правило, можно обратиться к чему-либо действительно.
Если Вы собираетесь быть выполнением большого добавления, , и Вы не будете делать произвольного доступа (такой как myArray[i]
). Вы могли рассмотреть использование связанного списка (LinkedList<T>
), потому что это никогда не должно будет "расти" как List<T>
реализация. Следует иметь в виду, тем не менее, что можно только действительно получить доступ к объектам в LinkedList<T>
реализация с помощью эти IEnumerable<T>
интерфейс.
Если я думаю, что собираюсь быть добавляющими объектами к набору много за его время жизни, чем я буду использовать Список. Если я буду знать наверняка, чем будет размер набора, когда его заявленное, то я буду использовать массив.
Другое время я обычно использую массив по Списку, когда я должен возвратить набор как свойство объекта - я не хочу вызывающие стороны, добавляющие объекты, что набор с помощью Списка Добавляет методы, но вместо этого хочет, чтобы они добавили объекты к набору через интерфейс моего объекта. В этом случае я возьму внутренний Список и назову ToArray и возвращу массив.
Это сообщение форума могло бы или не могло бы быть несколько полезным Вам относительно эффективности различных типов массива: массивы C# - многомерный по сравнению с лексикографическим
Вы корректны, массив является большим для взлетов взгляда. Однако модификации к размеру массива являются дорогостоящими.
необходимо использовать контейнер, который поддерживает возрастающие корректировки размера в сценарии, где Вы изменяете размер массива. Вы могли использовать ArrayList, который позволяет Вам устанавливать начальный размер, и Вы могли постоянно проверять размер по сравнению со способностью и затем увеличивать способность большим блоком для ограничения количества, изменяет размеры.
Или Вы могли просто использовать связанный список. Тогда однако посмотрите, взлеты являются медленными...
Стандартный массив должен быть определен с длиной, которая резервирует всю память, в которой он нуждается в непрерывном блоке. Добавление объекта к массиву вставило бы его блока уже зарезервированной памяти.
Массивы являются большими для немногих записей и многих чтений, особенно те из повторяющейся природы - для чего-либо еще, используют одну из многих других структур данных.
ArrayList и Список выращивают массив на больше чем один при необходимости (я думаю, что это путем удвоения размера, но я не проверил источник). Они - обычно лучший выбор, когда Вы создаете динамично размерный массив.
то, Когда Ваши сравнительные тесты указывают, что массив изменяет размеры, серьезно замедляется, Ваше приложение (помните - преждевременная оптимизация является корнем всего зла), можно оценить запись пользовательского класса массива с настроенным поведением изменения размеров.
Когда массив изменен, новый массив должен быть выделен, и скопированное содержание. Если Вы только изменяете содержание массива, это - просто присвоение памяти.
Так, Вы не должны использовать массивы, когда Вы не будете знать размера массива, или размер, вероятно, изменится. Однако, если у Вас есть массив фиксированной длины, они - простой способ получить элементы индексом.
Если Вы собираетесь быть добавляющими/удаляющими элементами много, просто используйте Список. Если это многомерно, можно всегда использовать List< List< интервал>> или что-то.
, С другой стороны, списки менее эффективны, чем массивы, если то, что Вы главным образом делаете, пересекающий список, потому что массивы - все в одном месте в Вашем кэше ЦП, где объекты в списке рассеиваются повсеместно.
, Если Вы хотите использовать массив для эффективного чтения, но Вы часто собираетесь быть "добавляющими" элементами, у Вас есть две основных опции:
1) Генерируют его как Список (или Список Списков) и затем используют ToArray () для превращения его в эффективную структуру массива.
2) Выделяют массив, чтобы быть больше, чем Вы нуждаетесь, затем помещаете объекты в предварительно выделенные ячейки. Если Вы заканчиваете тем, что нуждались еще в большем количестве элементов, чем Вы предварительно выделили, можно просто перераспределить массив, когда он заполняется, удваивая размер каждый раз. Это дает O (зарегистрируйте n), изменение размеров производительности вместо O (n) как он было бы с массивом reallocate-once-per-add. Обратите внимание, что это в значительной степени, как StringBuilder работает, давая Вам более быстрый способ постоянно добавить к строке.
В целом я предпочитаю избегать использования массива. Просто используйте List< T>. Это использует динамично измеренный массив внутренне и достаточно быстро для большей части использования. При использовании массивов multi-dimentional используйте List< List< List< T>>>, если Вы имеете к. Дело не в этом намного хуже с точки зрения памяти, и намного более просто добавить объекты к.
, Если Вы находитесь в 0,1% использования, которое требует экстремальной скорости, удостоверьтесь, что это - Ваши доступы списка, которые являются действительно проблемой, прежде чем Вы попытаетесь оптимизировать его.
Это действительно зависит от того, под чем Вы подразумеваете, "добавляют".
, Если Вы имеете в виду:
T[] array;
int i;
T value;
...
if (i >= 0 && i <= array.Length)
array[i] = value;
Затем нет, это не создает новый массив и является на самом деле самым быстрым способом изменить любой вид IList в.NET.
, однако, при использовании чего-то как ArrayList, Список, Набор, и т.д. затем называя "Добавить" метод может создавать новый массив - но они умны об этом, они только изменяют размеры 1 элементом, они растут геометрически, поэтому если Вы добавляете, что много значений только время от времени будет, это должно выделить новый массив. Даже тогда можно использовать свойство "Capacity", чтобы вынудить его вырасти перед рукой, если Вы знаете, сколько элементов Вы добавляете (list.Capacity += numberOfAddedElements
)
Обычно, если у Вас должно быть ЛУЧШЕЕ индексируемое выполнение поиска, лучше создавать Список сначала и затем превращать его в массив, таким образом платя маленький штраф сначала, но избежав немного позже. Если проблема - то, что Вы будете постоянно добавлять новые данные и удалять старые данные тогда, можно хотеть использовать ArrayList или Список для удобства, но иметь в виду, что они - просто Массивы особого случая. Когда они "растут", они выделяют абсолютно новый массив и копируют все в него, которое является чрезвычайно медленным.
ArrayList является просто Массив, который растет при необходимости. Добавьте амортизируется O (1), просто стараться удостовериться, что изменения размеры не произойдет в плохое время. Вставка является O (n), все объекты направо должны быть отодвинуты. Удалите O (n), все объекты направо должны быть отодвинуты.
Также важный, чтобы иметь в виду, что Список не является связанным списком. Это - просто введенный ArrayList. Список документация действительно отмечает, что это работает лучше в большинстве случаев, но не говорит почему.
лучшая вещь сделать состоит в том, чтобы выбрать структуру данных, которая соответствует Вашей проблеме. Это зависит тот МНОГО вещей и таким образом, можно хотеть просмотреть Система. Наборы. Универсальный Пространство имен.
В данном случае я сказал бы, что, если бы можно придумать хорошее значение ключа , Словарь был бы лучшим выбором. Это имеет, вставляют и удаляют, который приближается к O (1). Однако даже со Словарем необходимо быть осторожными, чтобы не позволить ему изменить размеры, это - внутренний массив (O (n) операция). Лучше давать им много комнаты путем определения larger-then-you-expect-to-use начальной способности в конструкторе.
- Рик