Большинство заданий в моей школе для начальных классов программирования требовало от меня использования массивов. Сейчас я работаю полный рабочий день, и я никогда не использовал массив для любого проекта, над которым я работал. Даже в существующих проектах я нигде не видел использования массивов. На мой взгляд, список проще в использовании и является стандартным. Почему профессора говорят студентам использовать массивы в своих заданиях? Это просто, чтобы студенты понимали основы?
Поскольку большинство университетов преподают Java, этот вопрос специфичен для Java.
java
programming-languages
programming-practices
Вой Хагрида
источник
источник
Ответы:
Поскольку массивы учат таким понятиям, как индексирование и границы, два принципиально важных понятия в компьютерном программировании.
Списки не являются "стандартом". Существует множество проблемных областей, для которых массивы идеально подходят.
источник
Вероятно, они хотели начать со структуры данных, которая наиболее точно отражает работу компьютера, поэтому вы знакомы с основами, прежде чем они начнут вводить абстракции более высокого уровня, такие как списки, с которыми легче работать. В противном случае вы не сможете понять, почему определенная структура или алгоритм медленны / быстры для одних операций, а не для других; если бы компьютерная память была фактически составлена из связанных списков, мир был бы совсем другим.
По той же самой причине мой первый класс программирования в колледже был на C, а остальные классы были на C ++, Java и других языках. Дело не в том, что C как-то лучше или проще, а в том, что C (и Array) ничего не скрывают от вас.
источник
Ответы выше велики, но я имею в виду другое.
main()
Метод Java означает, что учащиеся сталкиваются с базовыми массивами очень рано, часто уже в первый день занятий. Зачем?Это первое, с чем вам придется иметь дело, чтобы написать Hello World и не только. (Я видел, что в некоторых курсах сначала используются обучающие IDE, такие как BlueJ, которые позволяют указывать и нажимать для запуска произвольных методов, но мы отложим их в сторону ...) Хотя, возможно, стоит потрудиться над некоторыми из Эти ключевые слова на какое-то время рано или поздно большинству учителей захочется их объяснить. Действительно, классический тестовый вопрос для начинающих состоит в том, чтобы попросить студентов объяснить значение каждого ключевого слова в базовой программе Hello World. И что мы находим как часть сигнатуры нашего основного метода? Массив (причина этого отчасти историческая. ArrayList не существовал в Java 1.0). Массивы являются частью этого базового набора знаний. Список нет.
Тем не менее, это не редкость, когда классы вводят ArrayList чуть позже в курс, особенно после того, как объекты и их использование были рассмотрены. Даже учебная программа AP Computer Science для Java включает в себя ArrayList (я знаю, что раньше, и Google, кажется, указывает, что он все еще делает), хотя он игнорирует тот факт, что ArrayList реализует List и остальную часть Collections Framework.
Наконец, мой опыт показывает, что университетские CS-программы используют Java как средство для изучения CS и концепций программирования, а не для обучения студентов тому, как стать хорошими Java-разработчиками. Некоторые программы могут быть более сфокусированы на привлечении профессиональных разработчиков, в то время как другие больше фокусируются на теории, но в любом случае, есть много, чтобы узнать о том, как использовать Java в реальной профессиональной работе, которая не будет преподаваться в большинстве учебных программ колледжа. Это варьируется от шаблонов проектирования и методов, подобных тем, которые используются в Effective Java, до таких сред, как Spring, Hibernate или JUnit, или даже от более распространенных вещей, таких как JSP или JDBC. Учитывая эту философию, выделение массивов над более часто используемым ArrayList имеет немного больше смысла.
источник
Одна из причин, по которой первоклассные классы программирования используют массивы, заключается в том, что профессора изначально изучили это до того, как мы начали использовать стандартные библиотеки с динамическими списками. Использование примитивных типов данных также более широко применимо: массивы существуют практически на любом компьютере. язык под солнцем (и может быть реализовано в нескольких инструкциях по сборке). Когда я только начинал изучать программирование, реализация связанного списка была одним из заданий.
Гораздо проще начать с первых принципов, а затем сказать: «Это базовая структура. Этот язык (или его библиотеки) дает вам эту высокоуровневую структуру данных, которая делает все это, но дает вам x, y и z», чем это значит: «Таковы эти высокоуровневые структуры данных, а теперь вот что скрыто». Обучение рассуждать о том, использовать ли LinkedList против ArrayList (или HashSet против TreeSet), обычно является курсом Алгоритмов второго или третьего курса. Списки и карты имеют одинаковые интерфейсы и дают одинаковые результаты, но могут иметь разное поведение в приложении любого размера. И как только вы выйдете из программирования 101, нет никакой гарантии, что в программировании 102 будет использоваться один и тот же язык. Если вы начинаете с концепции массива, вы можете просто сказать:
Еще одна причина, по которой во вводном курсе предпочтение отдается «массиву», а не «списку», состоит в том, что массивы очень просты для понимания: массив из 20
bytes
занимает 20 байтов (плюс пара, указывающая конец массива или длину, в зависимости от реализации). ).«Список» - это совершенно другой источник рыбы и может быть реализован разными способами (ArrayList, LinkedList и, возможно, парой, которую я забыл), с принципиально разными характеристиками производительности. Не понимая начинку , что различные классы Списка делают, вы не можете иметь содержательную дискуссию о том, когда следует использовать
List foo = new ArrayList()
противList foo = new LinkedList()
. Если вы попытаетесь заставить студента использовать реализацию List, кто-то спросит, почему вы используете ArrayList вместо одной из других реализаций. И «ArrayList» включает в себя слово «Array» и поддерживается одним, так что это действительно не огромный логический переход от «массива» к «ArrayList».Вопреки распространенному мнению, существуют ситуации, в которых имеет смысл использовать массивы над списками, особенно когда вы имеете дело со списком статического размера. Вот пара:
foo[n]
разыменовываете и выполняет некоторую арифметику указателей за кадром, в то время какfoo.get(n)
должен разыменовать, выполнить вызов метода, сделать вторую разыменование, а затем, возможно, сделать арифметику указателя (если вы используете ArrayList; потенциально LinkedLists должен выполнять итерации по каждому элементу списка).int[] foo = new int[]{1, 2, 3, 4, 5}
против предложений в другом вопросе StackOverflowисточник
perm
этоint[256]
содержит перестановку, можно легко инвертировать ее с помощью массива:int[] inv = new int[256]; for (int i=0; i<256; i++) inv[perm[i]]=i;
я не думаю, что что-либо, что можно написать с помощью,ArrayList<>
будет таким же чистым.ArrayList
можно было бы легко получить конструктор, который создает инициализированный по умолчанию список определенного размера.get
иset
не вставал.get
иset
может быть встроено , что-то вродеmyList.set(23,myList.get(23)+1)
будет далеко не так эффективно, какmyArray[23]+=1
. Кроме того, даже для типов, которые не нуждаются в упаковке, я был бы очень удивлен, если бы любой JITter мог что-либо эквивалентноfor (i=0; i<1000; i++) myList2.set(i+2000,myList2.get(i+3000));
чему-либо, чья производительность была бы где-то рядом.System.arrayCopy(myArray1,3000,myArray2,2000,1000);
Нет причины, по которой тип динамического массива фреймворка не должен предлагать быструю операцию копирования диапазона, но ява нет.Java позволяет хранить переменные любого типа в массивах. Напротив,
ArrayList
позволяет только хранение ссылок. Таким образом, можно бесполезно обсуждатьArrayList
без предварительного рассмотрения того, как автобокс преобразует примитивы в ссылочные типы и как автоматическая распаковка иногда преобразует ссылочные типы в примитивы:Если бы код использовал
int[3]
скорее вместоArrayList
, то не было бы никаких сюрпризов. Все три элемента будут сравниватьсяi
друг с другом. ИспользуяArrayList
, однако, даже если все три элемента списка будут всегда сравниваться равнымиi
, а первый и третий всегда будут сравниваться равными друг другу, первые два элемента будут равны друг другу только тогда, когдаi
1, 10 или 100, но (на большинстве реализаций) не когдаi
1000 или 10000.источник
Integer
класс имеет вложенный класс,IntegerCache
который называется предварительно инициализированнымиInteger
объектами для диапазона значений, который обычно расширяется -128..127; для помещения значения за пределы этого диапазона потребуется создать новый объект, но помещение значения в пределах кэшированного диапазона просто вернет ссылку на один из предварительно инициализированных объектов, хранящихся вIntegerCache.cache
. Любой хороший Java-программист должен знать, чтоInteger
переменные двух типов, инкапсулирующие одно и то же значение, могут сравниваться или не совпадать, но слишком раннее внедрение этой идеи может заставить студентов бежать в ужасе.==
. Учитывая вероятность того, что автоматическое распаковывание может сработать, я был бы склонен полностью его запретить, но его поведение==
особенно ужасно.==
Оператор также плохо ведет себя в подобных случаях16777217==16777216f
[отчетам истинных], и неявные преобразования дляlong v=Math.Round(123456789), w=Math.Round(123456789012345)
склонны к неожиданным [вы можете догадаться , что эти выражения будут давать?]IntegerCache
, конечно, бывают моменты, когда это может помочь производительности, но это может часто вызывать код, который просто прост для работы. В некотором смысле мне хотелось бы, чтобы существовал режим, в котором бокс квазислучайно возвращал объекты из двух целочисленных кешей и квазислучайно заменял элементы кеша новыми, чтобы код, основанный на поведении бокса значений -128..127, был бы вряд ли удастся очень долго.Я думаю, что имеет смысл научить сначала использовать массивы из-за того, что
ArrayList
использует массив внутри. УArrayList
класса есть переменная-член,elementData
которая называетсяObject
массивом.Из
ArrayList
исходного кода JDK :Когда вы добавляете, обновляете, извлекаете или удаляете элементы из него,
ArrayList
он использует этот внутренний массив для выполнения этих операций. Как уже указал пользователь Ixrec -ArrayList
это просто абстракция более высокого уровня, с которой обычно легче работать.источник
Java
- Он спрашивал, зачем учить массивы, когда обычно вы можете использоватьArrayList
. У Java нет указателей. Правильно или нет, я придерживаюсь мнения, что C / C ++ - лучший язык для начинающих, чем Java. Многие темы в программировании могут быть лучше поняты благодаря знанию C / C ++.Если предположить, что с этим списком действительно легче работать, это не имеет значения. Обучение - это больше «от базового к сложному», чем от «простого к сложному». Если бы основы не были важны, то информатика не была бы академической областью. Вы можете просто научиться объединять приложения, используя существующие фреймворки / библиотеки, из онлайн-учебников. (Конечно, кто-то должен писать эти библиотеки ... а кто-то должен реализовывать
ArrayList
в первую очередь ....)источник
ArrayList
может быть лучше обработано с использованием отдельного массива и счетчика «liveItems», за исключением того, что нет удобного способа работать с массивом и считать вместе, кроме как путем их агрегирования.Это потому, что самое важное в академическом образовании - научить вас использовать правильную терминологию для описания того, что вы делаете.
Список - это нечто иное, чем этот массив. и вы не можете использовать
java.util.List
в Java, потому что это интерфейс. Вы обычно используете,java.util.ArrayList
который является реализацией List, это не список, а объектная оболочка вокруг динамического массива. Итак, вы говорите, что используете «Список», но вы используете массив.Разумно пропустить этот терминологический хаос и просто использовать массивы, чтобы узнать, что такое массив. Если вы используете массивы в Java, по крайней мере, вы используете массивы.
Честно говоря, это также аргумент, почему обучение программированию на Java не является хорошей идеей. Трудно правильно выучить основные понятия программирования.
источник
Вы буквально никогда не видели и не использовали никаких массивов вообще? Мы используем их постоянно, помимо списков. Мы обычно не используем Java, но мы используем множество других языков, которые имеют очевидное сходство.
Между массивами и списками один легче и, кроме того, более точен, в то время как другой обладает большей функциональностью. Как общее правило в программировании, когда есть два схожих типа, которые в основном разделены по этим линиям, вы должны выбрать более легкий, если вам действительно не нужен более изящный. В дополнение к сокращению накладных расходов, это фактически помогает контролировать количество беспорядка и состояния в программе и особенно ее коде . Если что-то пойдет не так во время тестирования, у вас будет меньше мест для поиска; и что еще более важно в случае массивов и списков, люди лучше понимают ограниченный объем того, для чего вы фактически используете его и пытаетесь делать с ним.
И да, с академической точки зрения, есть дополнительная причина обучения студентов основам. Однако это идет немного глубже. Массивы и списки являются хорошим примером более объемных типов, которые часто просто строятся поверх базовых экземпляров более легких типов, а часто просто оборачиваются вокруг них. Даже если списки не имеют базовых массивов, они ведут себя внешне так же, как и они. Одна часть обучения кого-либо тому, что такое List, состоит в том, чтобы научить его, что такое массив.
Я мог видеть, что это может выйти из-под контроля в языке, подобном C ++, где массивы в принципе не могут быть более урезаны, чем они есть, но в языках более высокого уровня они почти списки сами по себе. Если они идеально соответствуют вашим потребностям в конкретной ситуации, зачем вам использовать что-то еще?
источник
T[]
будет готов, прямо у ворот, принимать элементы в любом порядке, в то время как новыйArrayList<T>
требует, чтобы элементы были добавлены по порядку, прежде чем они могут быть изменены. AT[]
можетT[]
относительно быстро скопировать произвольный диапазон элементов в другой схожий по размеру диапазон , приArrayList<T>
этом потребуется считывать элементы по отдельности из одного списка и сохранять их в другом - гораздо медленнее и менее удобно.