Warum unterrichten Schulen Arrays über List? [geschlossen]

36

Die meisten Aufgaben in meiner Schule für die anfänglichen Programmierstunden erforderten die Verwendung von Arrays. Ich arbeite jetzt ganztägig und habe nie ein Array für ein Projekt verwendet, an dem ich gearbeitet habe. Selbst in den bestehenden Projekten habe ich nie die Verwendung von Arrays gesehen. Meiner Meinung nach ist List einfacher zu bedienen und ein Standard. Warum fordern Professoren die Studenten auf, Arrays in ihren Aufgaben zu verwenden? Ist es nur so, dass die Schüler die Grundlagen verstehen?

Da die meisten Universitäten Java unterrichten, ist diese Frage spezifisch für Java.

Heult Hagrid
quelle
7
Arrays sind grundlegender.
user253751
Kommentare sind nicht für eine längere Diskussion gedacht. Diese Unterhaltung wurde in den Chat verschoben .
Weltingenieur

Antworten:

120

Weil Arrays Konzepte wie Indizierung und Schranken lehren, zwei grundlegend wichtige Konzepte in der Computerprogrammierung.

Listen sind kein "Standard". Es gibt eine Vielzahl von Problembereichen, für die Arrays perfekt geeignet sind.

Robert Harvey
quelle
Kommentare sind nicht für eine längere Diskussion gedacht. Diese Unterhaltung wurde in den Chat verschoben .
Weltingenieur
48

Sie wollten wahrscheinlich mit der Datenstruktur beginnen, die die Funktionsweise eines Computers am genauesten widerspiegelt. Daher sind Sie mit den Grundlagen vertraut, bevor Sie übergeordnete Abstraktionen wie Listen einführen, die die Arbeit mit dem Computer erleichtern. Andernfalls könnten Sie nicht verstehen, warum eine bestimmte Struktur oder ein bestimmter Algorithmus für einige Operationen langsam / schnell ist und für andere nicht. Wenn der Computerspeicher tatsächlich aus verknüpften Listen bestehen würde, wäre die Welt ein ganz anderer Ort.

Aus dem gleichen Grund war meine erste Programmierstunde am College in C, und der Rest der Stunden war allesamt in C ++, Java und anderen Sprachen. Es ist nicht so, dass C irgendwie besser oder einfacher ist, sondern dass C (und Array) nichts vor Ihnen verbirgt.

Ixrec
quelle
7
Eine Liste ist in echtem Code einfacher zu bearbeiten, aber ein Array ist einfacher (vollständig) zu verstehen und wichtiger zu verstehen, da es grundlegend und universell ist, während dies bei (Java) nicht der Fall ist. Zumindest ist das meine Meinung.
Ixrec
21
Eine Zuweisung, in der Sie Daten in einem Array speichern und später darauf zugreifen, ist eine Datenstrukturzuweisung . Sie haben es vielleicht nicht bemerkt. Sie müssen sich fragen, was bessere Ingenieure hervorbringt, die grundlegenden Rechenmodelle versteht oder die Standardbibliothek einer Sprache lernt? Die allgemeine Übereinstimmung (und ich stimme zu, fwiw) ist, dass Sie nicht viel von dem Bibliotheksinhalt verstehen werden, ohne zuerst die Grundlagen der Berechnung zu verstehen.
Kent A.
12
LinkedList, ArrayList, OrderedList usw. Welche Liste sollten Sie zuerst lernen? Wie schätzen Sie es, was sie für Sie tun, wenn Sie nicht verstehen, warum sie überhaupt existieren?
Kent A.
10
+1 an @KentAnderson. Die Schulen müssen Ingenieure hervorbringen, die die Datenstrukturen auf niedrigem Niveau verstehen. im Idealfall Ingenieure, die die grundlegenden Strukturen in C leicht implementieren können. Jedes andere Programm ist lediglich eine JavaSchool.
Christian Willman
2
"Sie wollten wahrscheinlich mit der Datenstruktur beginnen, die die Funktionsweise eines Computers am genauesten darstellt." - Wie steht es also mit Computern mit listen- oder objektstrukturiertem Speicher? "Es ist nicht so, dass C irgendwie besser oder einfacher ist, sondern dass C (und Array) nichts vor dir verbirgt." - Es sei denn, Ihr Computer verfügt nicht über Zeiger wie AS / 400, auf denen C im Wesentlichen in einer VM ausgeführt wird und so ziemlich alles für Sie verbirgt .
Jörg W Mittag
21

Die Antworten oben sind großartig, aber ich habe andere im Sinn. Die main()Methode von Java bedeutet, dass die Schüler sehr früh auf grundlegende Anordnungen stoßen, oft schon am ersten Kurstag. Warum?

public static void main(String[] args)

Es ist das Erste, mit dem Sie sich befassen müssen, um Hello World und darüber hinaus zu schreiben. (Ich habe gesehen, dass in einigen Kursen zuerst IDEs wie BlueJ verwendet werden, mit denen Sie beliebige Methoden mit einem Mausklick ausführen können, aber wir werden diese beiseite legen ...) Es kann sich auch lohnen, einige davon zu übergeben Diese Schlüsselwörter werden die meisten Lehrer früher oder später für eine Weile erklären wollen. In der Tat besteht eine klassische Anfängerfrage darin, die Schüler zu bitten, die Bedeutung der einzelnen Schlüsselwörter in einem grundlegenden Hello World-Programm anzugeben. Und was finden wir als Teil unserer Hauptmethodenunterschrift? Ein Array (Der Grund dafür ist teilweise historisch. ArrayList war in Java 1.0 nicht vorhanden). Arrays sind Teil dieses Grundwissens. Liste ist nicht.

Das heißt, es ist nicht ungewöhnlich, dass Klassen ArrayList etwas später in den Kurs einführen, insbesondere wenn Objekte und deren Verwendung behandelt wurden. Sogar das AP Computer Science-Curriculum für Java enthält ArrayList (ich weiß, dass es früher verwendet wurde, und Google scheint darauf hinzuweisen, dass dies immer noch der Fall ist), obwohl es die Tatsache ignoriert, dass ArrayList List und den Rest des Collections Frameworks implementiert.

Schließlich ist es meine Erfahrung, dass Universitäts-CS-Programme Java verwenden, um CS- und Programmierkonzepte zu erkunden, anstatt den Schülern beizubringen, gute Java-Entwickler zu werden. Einige Programme konzentrieren sich eher darauf, professionelle Entwickler herauszufordern, während andere sich eher auf die Theorie konzentrieren. In beiden Fällen gibt es jedoch noch viel zu lernen, wie man Java in einer echten professionellen Arbeit einsetzt, die in den meisten Lehrplänen am College nicht gelehrt wird. Dies reicht von Entwurfsmustern und -techniken wie in Effective Java bis hin zu Frameworks wie Spring, Hibernate oder JUnit oder sogar noch häufigeren Dingen wie JSP oder JDBC. Unter Berücksichtigung dieser Philosophie ist es etwas sinnvoller, Arrays über die am häufigsten verwendete ArrayList zu betonen.

Zach Lipton
quelle
3
@ Deduplicator sicher. Es war für meinen Standpunkt zu Arrays einfach nicht relevant, deshalb habe ich es weggelassen. Ich habe auch System.out.println ("Hello World!") Nicht aufgenommen. entweder.
Zach Lipton
+1 für Konzepte vs. effektive Techniken für die "reale Welt". Niemand unterrichtete Versionskontrolle, zumindest nicht, als ich in der Schule war - aber dann bin ich uralt :)
David
Ich habe eine Betriebssystemklasse besucht, in der wir verschiedene Teile wie einen Scheduler implementieren mussten. Wir haben uns (ausschließlich) auf ein solches Stück konzentriert, weil wir zu diesem Zeitpunkt nicht in der Lage waren, mehr zu tun . Aber der Gedanke, all diese Stücke gleichzeitig zum Laufen zu bringen, gab mir (den Beginn) ein Verständnis für die Komplexität der "realen Welt" -Entwicklung / "Programmierung im Großen".
David
14

Ein Grund, warum Programmierklassen im ersten Jahr Arrays verwenden, ist Legacy: So haben es die Professoren ursprünglich gelernt, bevor wir mit der Verwendung von Standardbibliotheken mit eingebauten dynamischen Listen begonnen haben Sprache unter der Sonne (und kann in einer Handvoll Montageanleitungen implementiert werden). Als ich das Programmieren zum ersten Mal lernte, war die Implementierung einer verknüpften Liste eine der Aufgaben.

Es ist viel einfacher, von den Grundprinzipien auszugehen und dann zu sagen: "Das ist die Grundstruktur. Diese Sprache (oder ihre Bibliotheken) bietet Ihnen diese übergeordnete Datenstruktur, die all das leistet, aber Ihnen x, y und z gibt." Es heißt: "Das sind also diese Datenstrukturen auf hoher Ebene. Hier ist, was unter der Haube ist." Zu lernen, wie man über die Verwendung einer LinkedList im Vergleich zu einer ArrayList (oder eines HashSet im Vergleich zu einem TreeSet) urteilt, ist normalerweise ein Algorithmuskurs im zweiten oder dritten Jahr. Listen und Karten haben die gleichen Oberflächen und führen zu den gleichen Ergebnissen, können sich jedoch in einer Anwendung jeder Größe dramatisch unterscheiden. Und wenn Sie Programmieren 101 verlassen, gibt es keine Garantie dafür, dass Programmieren 102 dieselbe Sprache verwendet. Wenn Sie vom Konzept eines Arrays ausgehen, können Sie einfach sagen "

Ein weiterer Grund für den Vorzug von "Array" gegenüber "List" in einem Einführungskurs ist, dass Arrays grundsätzlich leicht zu verstehen sind: Ein Array von 20 bytesbenötigt 20 Bytes (plus ein Paar, um je nach Implementierung entweder das Ende des Arrays oder die Länge anzugeben) ).

Eine "Liste" ist ein völlig anderer Fischkessel und kann auf viele verschiedene Arten implementiert werden (ArrayList, LinkedList und wahrscheinlich ein paar, die ich vergessen habe), mit grundlegend unterschiedlichen Leistungsmerkmalen. Ohne die Eingeweide der verschiedenen List-Klassen zu verstehen, können Sie nicht sinnvoll diskutieren, wann Sie List foo = new ArrayList()vs. verwenden sollten List foo = new LinkedList(). Wenn Sie versuchen , die Schüler zu bekommen eine Liste Implementierung zu verwenden, jemand wird sich fragen , warum Sie Arraylist verwenden anstelle von einer der anderen Implementierungen. Und "ArrayList" enthält das Wort "Array" und wird durch eins unterlegt, so dass es wirklich kein großer logischer Sprung von "Array" zu "ArrayList" ist.

Entgegen der landläufigen Meinung gibt es Situationen, in denen es sinnvoll ist, Arrays über Listen zu verwenden, insbesondere wenn Sie mit einer Liste statischer Größen arbeiten. Hier sind ein paar:

  • Das Nachschlagen und die Iteration sind etwas schneller, da Sie sich nicht mit dem Overhead des Methodenaufrufs befassen: foo[n]Dereferenzierungen und einige Arithmetikaufgaben für Zeiger im Hintergrund, während foo.get(n)eine Dereferenzierung, ein Methodenaufruf, eine zweite Dereferenzierung und dann möglicherweise eine Zeigerarithmetik durchgeführt werden müssen (Wenn Sie eine ArrayList verwenden, müssen LinkedLists möglicherweise jedes Element der Liste durchlaufen.)
  • Die Initialisierung ist viel sauberer: int[] foo = new int[]{1, 2, 3, 4, 5}im Vergleich zu den Vorschlägen in einer anderen StackOverflow-Frage
Carl C.
quelle
Ein weiteres Szenario, in dem Arrays Arrays massiv schlagen, besteht darin, dass die Reihenfolge, in der Elemente verfügbar werden, mit der Reihenfolge übereinstimmt, in der ihre endgültigen Positionen bekannt werden, jedoch nicht mit der endgültigen Reihenfolge übereinstimmt. Wenn permes ein ist int[256], das eine Permutation enthält, kann man es leicht mit einem Array invertieren: int[] inv = new int[256]; for (int i=0; i<256; i++) inv[perm[i]]=i; Ich glaube nicht, dass irgendetwas, mit dem man schreiben könnte, ArrayList<>so sauber wäre.
Superkatze
@supercat Das ist nicht wirklich ein Problem mit dynamischen Arrays, nur die bestimmte Implementierung; ArrayListhätte leicht einen Konstruktor bekommen können, der eine standardmäßig initialisierte Liste einer bestimmten Größe erstellt.
Doval,
Haben Sie Quellen, um die Behauptung zu sichern, dass eine Array-Liste den Aufwand für Methodenaufrufe bewältigen muss? Theoretisch tut es, aber in der Praxis würde ich , wenn überrascht sein getund setnicht inlined bekommen.
Doval,
@Doval: Es gibt keinen Grund, warum eine gut konzipierte Sprache / ein gut gestaltetes Framework keinen dynamischen Array-Typ liefern sollte, mit dem Elemente in einer anderen Reihenfolge hinzugefügt werden können, aber Java liefert keinen solchen Typ.
Supercat
@Doval: Auch wenn getund setkann ausgekleidet werden, so etwas myList.set(23,myList.get(23)+1)wird bei weitem nicht so effizient sein wie myArray[23]+=1. Sogar für Typen, die kein Boxen benötigen, wäre ich sehr überrascht, wenn ein JITter irgendetwas enthalten könnte, das mit irgendetwas vergleichbar ist, for (i=0; i<1000; i++) myList2.set(i+2000,myList2.get(i+3000));dessen Leistung irgendwo in der Nähe System.arrayCopy(myArray1,3000,myArray2,2000,1000); liegt. aber Java nicht.
Supercat
7

Mit Java können Variablen jeden Typs in Arrays gespeichert werden. ArrayListErmöglicht dagegen nur die Speicherung von Referenzen. Man kann daher nicht sinnvoll diskutieren, ArrayListohne vorher abzudecken , wie Auto-Boxing Primitive in Referenztypen umwandelt und wie Auto-Unboxing manchmal Referenztypen in Primitive umwandelt:

for (int i=10; i<=10000; i*=10)
{
    ArrayList<Integer> l = new ArrayList<Integer>();
    l.add(i);
    l.add(i);
    l.add(l.get(0));
    System.out.print("i=" + i);
    System.out.print(" #0==i:" + (l.get(0)==i));
    System.out.print(" #1==i:" + (l.get(1)==i));
    System.out.print(" #2==i:" + (l.get(2)==i));
    System.out.print(" #0=#1:" + (l.get(0)==l.get(1)));
    System.out.print(" #1=#2:" + (l.get(1)==l.get(2)));
    System.out.println(" #0=#2:" + (l.get(0)==l.get(2)));
}

Wenn der Code eine int[3]anstelle einer verwendet hätte ArrayList, würde es keine Überraschungen geben. Alle drei Elemente würden gleich iund miteinander vergleichen . Wenn ArrayListjedoch alle drei Elemente der Liste immer gleich isind und das erste und dritte immer gleich sind, gleichen sich die ersten beiden Elemente nur dann, wenn i1, 10 oder 100, aber (bei den meisten Implementierungen) nicht bei i1000 oder 10000.

Superkatze
quelle
Können Sie erklären, warum # 0 und # 1 gleich sind, wenn sie 1 oder 10 oder 100 sind? Ich folgte bis zu diesem Punkt.
Matthew Read
2
@MatthewRead: Die IntegerKlasse hat eine verschachtelte Klasse namens, IntegerCachedie vorinitialisierte IntegerObjekte für einen Wertebereich enthält, der normalerweise -128..127 beträgt. Wenn Sie einen Wert außerhalb dieses Bereichs boxen, müssen Sie ein neues Objekt erstellen. Wenn Sie jedoch einen Wert innerhalb des zwischengespeicherten Bereichs boxen, wird lediglich ein Verweis auf eines der vorinitialisierten Objekte zurückgegeben, die in gespeichert sind IntegerCache.cache. Jeder gute Java-Programmierer muss sich darüber im Klaren sein, dass zwei IntegerVariablen, die denselben Wert enthalten, möglicherweise gleich sind oder nicht, aber eine zu frühe Einführung dieser Idee kann die Schüler vor Angst fliehen lassen.
Superkatze
Ich hätte nie gedacht, dass es an vorinitalisierten Objekten liegt. Danke für die Information!
Matthew Read
1
@MatthewRead: Ich wünschte, Java hätte bestimmte Arten der impliziten Konvertierung mit nicht zugelassen ==. In Anbetracht der Möglichkeit, dass Auto-Unboxing werfen kann, würde ich es ganz verbieten, aber sein Verhalten mit ==ist besonders schrecklich. Der ==Operator verhält sie auch schlecht in Fällen wie 16777217==16777216f[Berichte wahr], und die impliziten Konvertierungen für long v=Math.Round(123456789), w=Math.Round(123456789012345)geeignet sind , unerwartet zu sein [kann man erraten , was diese Ausdrücke ergeben wird?]
supercat
Was IntegerCachegibt es sicherlich Zeiten , wenn es Leistung helfen kann, aber es kann häufig Ursache - Code, der an Just Plain zu irgendwie-sorta Arbeit. In mancher Hinsicht wünschte ich mir, es gäbe einen Modus, in dem das Boxen Objekte aus zwei ganzzahligen Caches quasi zufällig zurückgibt und Cache-Elemente quasi zufällig durch neue ersetzt, sodass der Code auf dem Boxverhalten der Werte -128..127 beruht Es ist unwahrscheinlich, dass dies sehr lange gelingt.
Supercat
6

Ich halte es für sinnvoll, zunächst zu lehren, wie Arrays ArrayListverwendet werden, da ein Array intern verwendet wird. Die ArrayListKlasse hat eine Member-Variable namens, elementDatadie ein ObjectArray ist.

Aus dem JDK- ArrayList Quellcode :

/**
 * The array buffer into which the elements of the ArrayList are stored.
 * The capacity of the ArrayList is the length of this array buffer.
 */
private transient Object[] elementData;

Wenn Sie Elemente hinzufügen, aktualisieren, abrufen oder entfernen ArrayList, werden diese Vorgänge über dieses interne Array ausgeführt. Wie der Benutzer Ixrec bereits betont hat, ArrayListhandelt es sich lediglich um eine übergeordnete Abstraktion, mit der in der Regel einfacher zu arbeiten ist.

Derek W
quelle
Ein Array verwendet jedoch intern einen Zeiger auf einen Speicherblock. Warum auf dieser spezifischen Abstraktionsebene anfangen?
Die Frage ist markiert als Java: Es wurde gefragt, warum Arrays unterrichtet werden, wenn dies normalerweise der Fall ist ArrayList. Java hat keine Zeiger. Richtig oder falsch, ich bin der Meinung, dass C / C ++ eine bessere Sprache für Anfänger ist als Java. Viele Themen der Programmierung lassen sich besser verstehen, wenn man sich mit C / C ++ auskennt.
Derek W
3

Angenommen, mit dieser Liste lässt sich in der Tat leichter arbeiten, wie Sie sagen - das ist eigentlich egal. Lernen ist mehr von "einfach bis komplex" als von "einfach bis schwer". Wenn Grundlagen nicht wichtig wären, wäre Informatik kein akademisches Gebiet. In Online-Tutorials können Sie einfach lernen, wie Sie Apps mithilfe vorhandener Frameworks / Bibliotheken zusammenklicken. (Natürlich muss jemand diese Bibliotheken schreiben ... und jemand muss sie zuerst implementieren ArrayList....)

Matthew Read
quelle
In vielen Fällen ArrayListkönnte diese Verwendung durch Verwendung eines separaten Arrays und der Anzahl "liveItems" besser gehandhabt werden, mit der Ausnahme, dass es keine bequeme Möglichkeit gibt, mit dem Array zu arbeiten und zusammen zu zählen, außer sie zu aggregieren.
Superkatze
2

Das Wichtigste in der akademischen Ausbildung ist, dass Sie lernen, die richtigen Begriffe zu verwenden, um Ihre Tätigkeiten zu beschreiben.

Liste ist etwas anderes als Array. und Sie können nicht java.util.Listin Java verwenden, weil es eine Schnittstelle ist. Normalerweise verwenden Sie, java.util.ArrayListwas eine List-Implementierung ist, keine Liste, sondern einen Objekt-Wrapper um ein dynamisches Array. Sie sagen also, Sie verwenden eine 'Liste', aber Sie verwenden ein Array.

Es ist sehr vernünftig, dieses terminologische Chaos zu überspringen und einfach Arrays zu verwenden, um den Schülern zu erklären, was Array ist. Wenn Sie Arrays in Java verwenden, verwenden Sie zumindest Arrays.

Ehrlich gesagt ist es auch das Argument, warum das Unterrichten von Programmierung mit Java keine gute Idee ist. Es ist schwer, die grundlegenden Konzepte der Programmierung richtig zu lernen.

Donau Seemann
quelle
Was ist mit Hashmap? Ein Array ist in
gewisser
@ Thufir Wie kann ein Array eine Hashmap sein? Das sind völlig andere Datenstrukturen.
Danubian Sailor
Sie können ein Array mit einer Hashmap darstellen. Was ist "grundlegender"? Ich würde sagen, Hashmap ist konzeptionell interessanter.
Thufir
1
@Thufir nein, das kannst du nicht. Sie können nur emulieren. Intern wird jede Datenstruktur so sein, wie sie ist. Das sind grundsätzlich und konzeptionell verschiedene Dinge. Aus diesem Grund ist es keine gute Idee, das Programmieren mit so abstrakten Sprachen wie Java oder JavaScript zu erlernen. Dort ist nicht klar, wie die Datenstrukturen wirklich sind.
Danubian Sailor
1

Sie haben buchstäblich noch nie ein Array gesehen oder benutzt? Wir verwenden sie ständig zusätzlich zu Listen. Wir verwenden normalerweise kein Java, aber wir verwenden viele andere Sprachen, die offensichtliche Ähnlichkeiten aufweisen.

Zwischen Arrays und Listen ist das eine leichter und darüber hinaus präziser, während das andere mehr Funktionen bietet. Als allgemeine Regel in der Programmierung sollten Sie, wenn es zwei ähnliche Typen gibt, die im Grunde nach diesen Grundsätzen unterteilt sind, den leichteren wählen, es sei denn, Sie benötigen tatsächlich den schickeren. Dies reduziert nicht nur den Overhead, sondern hilft auch dabei, die Unordnung und den Status im Programm und insbesondere den Code im Griff zu behalten . Wenn beim Testen etwas schief geht, müssen Sie weniger nachsehen. und was noch wichtiger ist, im Fall von Arrays im Vergleich zu Listen erhalten die Benutzer eine bessere Vorstellung von dem begrenzten Umfang dessen, wofür Sie es tatsächlich verwenden und versuchen, damit umzugehen.

Und ja, aus akademischer Sicht gibt es den zusätzlichen Grund, den Schülern die Grundlagen beizubringen. Dies geht jedoch etwas tiefer. Arrays und Listen sind ein gutes Beispiel für umfangreichere Typen, die häufig nur auf Basisinstanzen der leichteren Typen erstellt werden und diese häufig nur umschließen. Auch wenn Listen keine zugrunde liegenden Arrays haben, verhalten sie sich äußerlich genauso wie sie. Ein Teil davon, jemandem beizubringen, was eine Liste ist, besteht darin, ihm beizubringen, was ein Array ist.

Ich konnte sehen, dass dies in einer Sprache wie C ++ möglicherweise aus dem Ruder läuft, wo Arrays im Grunde genommen nicht einfacher als sie sind, aber in höheren Sprachen sind sie fast Listen für sich. Wenn sie in einer bestimmten Situation perfekt zu Ihren Bedürfnissen passen, warum sollten Sie dann etwas anderes verwenden?

Panzerkrise
quelle
Ich würde nicht sagen, dass eine Liste "mehr" Funktionen hat, genauso wie sie "andere" Funktionen hat. Ein neues T[]Gerät ist direkt vor dem Tor bereit, Elemente in beliebiger Reihenfolge zu akzeptieren, während es ArrayList<T>erforderlich ist, dass Elemente der Reihe nach hinzugefügt werden, bevor sie geändert werden können. A T[]kann einen beliebigen Bereich von Elementen T[]relativ schnell in einen Bereich mit ähnlicher Größe kopieren , während ArrayList<T>Elemente einzeln aus einer Liste gelesen und in der anderen gespeichert werden müssen - viel langsamer und unbequemer.
Supercat