Подтвердить что ты не робот

Когда необходим общий массив - случай

Этот Q должен искать примерный случай, когда общий массив абсолютно необходим.

Генерики и массивы "не смешиваются хорошо".

Есть ли случай, когда общий ArrayList не будет делать - общий массив не имеет замены и должен использоваться.

Эффективная Java оставляет дверь открытой для общих массивов, говоря, что могут быть случаи, когда необходим общий массив.

Я использовал ArrayList без каких-либо недостатков и не могу придумать такой случай.

ТИА.

Примечание: я видел их:

Наряду с некоторыми другими обсуждениями.

4b9b3361

Ответ 1

Некоторые моменты:

  • Если у вас есть некоторая "устаревшая" библиотека, вы привязаны к типам, которые они используют. Это могут быть массивы.

  • Если вы обрабатываете собственный код, тогда массивы будут более естественным способом обмена данными с собственным кодом.

  • Если вы обращаетесь к двоичным данным (например, к звуковым файлам или тому подобным), то использование массива может помочь.

  • Если вы обрабатываете большое количество двоичных данных, тогда массив может быть более эффективным.

Таким образом, существует множество причин, по которым массив может быть полезен (особенно с примитивными типами).

Если вы обрабатываете объекты только тогда, проще всего использовать List.

Ответ 2

Я бы сказал, что Блох означает удобство вместо необходимости, массивы - это более простые структуры, которые легче обрабатывать.

В качестве структуры данных, с точки зрения функциональности, ArrayList взаимозаменяемы с массивом.

Массивы, очевидно, более скудны по памяти, но требуют дополнительных усилий для получения некоторых базовых функций (например, изменение массива вручную, когда исходный массив недостаточно велик для хранения нового элемента), но другие функции уже предоставлены средой выполнения (Arrays).

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

Ответ 3

Некоторые мысли:

array - это базовый тип данных, необходимый на любом императивном языке (возможно, в замаскированной форме). Без array, как мы можем реализовать ArrayList?:)

Однако мы могли бы замаскировать array как "обычный" тип. Например, мы могли бы ввести собственный тип lang.lang.Array<E>, который будет массивом, и исключить текущий тип array в Java. (Игнорирование примитивных массивов, эта другая тема). Все будет хорошо.

Тем не менее, у нас нет роскоши, чтобы "улучшить" и "очистить" язык таким образом, чтобы нарушить обратную совместимость.

До введения дженериков array можно рассматривать как дженерики бедных людей. Мы не могли выразить ArrayList<String>, но мы могли бы сделать String[]. Вот почему многие старые API возвращают массив вместо некоторого типа коллекции, потому что массив был более безопасным для типов. array является даже со-вариантом... своего рода.

После введения дженериков варианты использования для array становятся намного меньше. Обычно вам следует избегать использования массива в публичном API. (Конечно, кроме var-arg foo(Bar...), который является массивом под капотом)

Но в коде реализации нам все еще нужно array, это базовая структура данных для построения более сложных структур данных. Для этого ArrayList, очевидно, более раздувается во многих случаях.

Теперь вопрос заключается в том, чтобы реализовать что-то вроде ArrayList<E>, следует ли использовать внутри E[] или Object[]? Из-за стирания, E[] более хлопотно - как говорится, "дженерики и массивы не смешиваются хорошо". Поэтому забудьте об этом, просто используйте Object[] и при необходимости сделайте приведение.

Ответ 4

An ArrayList требует небольшого количества дополнительной памяти по сравнению с массивом. Это, очевидно, верно, поскольку ArrayList реализуется как оболочка вокруг массива. По моей приблизительной оценке, ArrayList будет потреблять дополнительные 16 байт.

При нормальных обстоятельствах это не о чем беспокоиться. Но если вы создаете очень большое количество массивов (миллионы/миллиарды), это может потенциально изменить ситуацию.

Существует также случай примитивных массивов. ArrayList ограничивается правилами для коллекций, поэтому он не может хранить примитивные элементы, а только соответствующую обертку объекта. Так, например, byte[] потребляет 1 байт на элемент, но ArrayList<Byte> потребляет 4 байта на элемент. Это может иметь значение, если ваши массивы потенциально очень большие.

Ответ 5

Как правило, ArrayList считается более благоприятным, чем массивы. Он обеспечивает те же функциональные возможности, хотя лучше интегрируется, особенно с другими типами из API Java Collection.

Следовательно, использование массивов может возникнуть из-за особых требований. С одной стороны, можно использовать библиотеку (или другой сторонний код), для которой требуются массивы.

С другой стороны, массивы еще работают лучше, чем ArrayList. Я создал Gist, который сравнивает использование ArrayList<Integer> с int[]. (Обратите внимание, что вы не можете использовать примитивы с ArrayList s.) Средние результаты для создания 1.000.000 случайных элементов и нахождения их максимума на моей машине:

Test case CREATE_ARRAY average time: 25.93 ms
Test case CREATE_ARRAY_LIST average time: 44.06 ms
Test case MAX_OVER_ARRAY average time: 1.44 ms
Test case MAX_OVER_ARRAY_LIST average time: 5.86 ms

Итак, мы окольными в 4 раза медленнее с ArrayList. Тем не менее, в нормальных случаях использования это можно смело считать микро-оптимизацией. Большинство случаев использования требуют качества кода кода при таких улучшениях производительности.

Ответ 6

[...] говоря, что может быть случаем, когда общий массив необходимо.

Кажется, Джошуа Блох просто хотел быть в безопасности, давая возможность, даже если он этого не знает.

Почему автор упоминает такую ​​точку без примера, если он знает, что есть один?

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

Сама структура данных одна и та же, помните Arrays.asList и ArrayList.toArray

Ответ 7

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

уроки оракула

Устранение отливок. Следующий фрагмент кода без дженериков требует кастинга:

List list = new ArrayList();
list.add("hello");
String s = (String) list.get(0);

При повторной записи для использования дженериков код не требует кастинга:

List<String> list = new ArrayList<String>();
list.add("hello");
String s = list.get(0);   // no cast

Ответ 8

Я сразу вспомнил пару вещей, когда я прочитал вопрос.

Один. Если вы используете Java Micro Edition, у вас может не быть ArrayList, доступного вам. Такие вещи довольно распространены, если вы когда-либо работаете над устаревшим кодом. Запись в .Net 1.1 или 2.0 очень похожа на сокращение ваших рук по сравнению с 4.0 и более поздними (на мой взгляд). Java Micro Edition похожа: если вы привыкли к Java 6+, то J2ME чувствует себя очень ограничительным. Этот вопрос обсуждает его немного, но я думаю, что я бы пошел с регулярным массивом, чем использовать вектор (который по этому потоку синхронизирован... Я не знаю, t глубже, чем это).

Два: если вы находитесь в встроенной системе и должны иметь жесткий контроль над размером массива. Другие ответы коснулись этого немного. IIrc по умолчанию функциональность ArrayList удваивается по размеру при изменении размера, но у меня возникли проблемы с поиском точной цитаты. Во встроенных системах с очень ограниченной памятью меня не удивило бы, если бы такой размер искажал больше, чем всю память в системе (например, ваш массив занимает 75% всей системной памяти, при изменении размера он будет пытаться занимают 150% памяти). Если вы используете массив и вручную управляете всеми изменениями, то это становится проблемой без проблем.