Интерфейс коллекции против массивов - PullRequest
43 голосов
/ 23 мая 2011

Мы узнаем об интерфейсе сбора, и мне было интересно, есть ли у вас какие-либо полезные советы для его общего использования?Что вы можете сделать с коллекцией, которую вы не можете сделать с массивом?Что вы можете сделать с массивом, который вы не можете сделать с коллекцией (кроме разрешения дубликатов)?

Ответы [ 5 ]

66 голосов
/ 24 мая 2011

Это легко, если вы думаете об этом так: коллекции лучше, чем массивы объектов, практически во всех отношениях.

Вы должны предпочитать List<Foo> над Foo[], когда это возможно. Рассмотрим:

  • Коллекция может быть изменяемой или неизменной. Непустой массив всегда должен быть изменяемым.
  • Коллекция может быть поточно-ориентированной; даже одновременно. Массив никогда не является безопасным для публикации в нескольких потоках.
  • Коллекция может разрешать или запрещать нулевые элементы. Массив всегда должен разрешать нулевые элементы.
  • Коллекция является типобезопасной; массив не является. Поскольку массивы "поддельные" ковариации, ArrayStoreException может привести к времени выполнения.
  • Коллекция может иметь тип, не подлежащий повторному назначению (например, List<Class<? extends E>> или List<Optional<T>>). С массивом вы получаете предупреждения компиляции и запутанные исключения во время выполнения.
  • Коллекция имеет полностью переработанный API; массив имеет только set-at-index, get-at-index и length.
  • Коллекция может иметь представления (неизменяемые, подсписки, фильтры ...). Нет такой удачи для массива.
  • Методы списка или набора equals, hashCode и toString выполняют то, что ожидают пользователи; эти методы в массиве делают все что угодно , но то, что вы ожидаете - распространенный источник ошибок.
  • По всем вышеперечисленным причинам сторонние библиотеки, такие как Guava, не будут беспокоиться о добавлении дополнительной поддержки массивов, фокусируясь только на коллекциях, так что возникает сетевой эффект.

Объектные массивы никогда не будут первоклассными гражданами в Java.

Некоторые из приведенных выше причин более подробно описаны в Effective Java, Second Edition , начиная со страницы 119.

Так зачем вам использовать массивы объектов?

  • Вы должны взаимодействовать с API, который их использует, и вы не можете исправить этот API
    • , поэтому конвертируйте в / из List как можно ближе к этому API, насколько это возможно
  • У вас есть надежный тест, который показывает, что вы действительно получаете лучшую производительность с ними
    • но тесты могут врать, и часто делают
  • Я не могу думать ни о каких других причинах
7 голосов
/ 23 мая 2011

Это в основном вопрос желаемого уровня абстракции .

Большинство коллекций могут быть реализованы в виде массивов, но для вашего удобства они предоставляют намного больше методов. Например, большинство реализаций коллекций, о которых я знаю, могут увеличиваться и уменьшаться в зависимости от спроса или выполнять другие операции «высокого уровня», которые не могут выполнять базовые массивы.

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

1 голос
/ 23 мая 2011

Подробности находятся во вспомогательных интерфейсах Collection, таких как Set, List и Map.Каждый из этих типов имеет семантику .Набор, как правило, не может содержать дубликаты и не имеет понятия порядка (хотя в некоторых реализациях он есть), следуя математической концепции набора.Список ближе всего к массиву.Карта имеет специфическое поведение для push и get.Вы нажимаете на объект его ключом, и вы получаете с тем же ключом.

В реализациях каждого типа коллекции есть еще больше деталей.Например, любая из коллекций на основе хеша (например, HashSet, HasMap) основана на методе hashcode (), который существует в любом объекте Java.

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

0 голосов
/ 23 мая 2011

Одним из преимуществ является интерфейс Iterator.То есть все Коллекции реализуют Итератор.Итератор - это объект, который знает, как перебирать заданную коллекцию и предоставлять программисту унифицированный интерфейс независимо от базовой реализации.То есть связанный список просматривается не так, как двоичное дерево, но итератор скрывает эти различия от программиста, упрощая программисту использование одной или другой коллекции.используйте различные реализации коллекций взаимозаменяемо, если клиентский код нацелен на интерфейс коллекции сам.

0 голосов
/ 23 мая 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...