Guten Tag, frohes neues Jahr. Fast hätte ich die
Vorlesung, zwangs die erste Vorlesung 2016 zu spät angefangen.
Das geht ja gut los. So, deswegen nochmal gesittet,
frohes neues Jahr. Wir haben uns ja jetzt länger nicht gesehen.
Es wird sich jetzt wieder ändern. Die nächsten vier Wochen,
inklusive Deezer, noch ein bisschen SE1,
dann ein paar Wochen Pause und dann noch 14 Mal SE2.
Das ist ein Angebot, keine Drohung.
Und dann müssen sie schon wieder
viel mehr
Heute. Heute werden Fried und ich ihn hoffentlich so einige Mysterien dessen,
womit sie sich jetzt schon in den letzten acht bis zehn
Wochen beschäftigt haben, werden wir ihnen erläutern können.
Also dass das keine Mysterien sind, dass das alles mit
der Hand am Arm implementiert worden ist. Und das Wesentliche,
Konstrukt anhand dessen wir ihnen das nahe bringen, werden,
sehen sie hier schon auch auf der ersten Folie.
Damit werde ich mich so ungefähr eine halbe Stunde lang beschäftigen heute.
Das ist das Array
Sie haben sich bis jetzt so mit verschiedenen Arten von Variablen beschäftigt,
als da wären Exemplarvariablen, lokale Variablen in Methoden.
Zum Beispiel, womit wir uns noch nicht beschäftigt haben,
so in der Tiefe sind sogenannte Sammlungen.
Array ist jetzt mal die erste Art von Sammlung,
mit der wir uns hier beschäftigen werden im Rahmen der Vorlesung.
Wir werden in den nächsten zwei, drei Wochen,
werden sie noch andere Arten von Sammlungen kennenlernen.
Aber das Array ist so eins der zentralen Konstrukte,
wenn es darum geht, mit Sammlungen, Mengen gleichartiger Objekte umzugehen.
Das wird sie für den Rest ihres Programmiererlebens, wird sie dieses Konstrukt nicht mehr verlassen.
Aber wir werden zuerst mal hier so die üblichen Sachen machen,
Deklaration, Erzeugung, Initialisierung und Verwendung von Arrays und dann,
während ich das mit Ihnen hier bespreche,
auch schon mal so die eine oder andere Programmierschwierigkeit,
Fehlerquelle liebe, besprechen,
die beim Umgang mit Arrays eine Rolle spielen,
also Arrays,
ich sage jetzt immer Arrays,
sage nicht Reihe oder Reihungen dazu
Und am Ende dieses Teils der Vorlesung dann nochmal ein klein wenig
auf die allgemeinen Eigenschaften, auch mit Blick darauf diskutieren,
die allgemeinen Eigenschaften von Aris diskutieren mit Blick darauf,
was wir noch so an anderen Arten von Sammlungen kennenlernen werden.
So im letzten Teil der Vorlesung werde ich noch was über sogenannte Klassenobjekte erzählen.
Das dient dazu, so ihr Grundverständnis von Java und darüber hinaus,
also von Objektorientierten Programmiersprachen ein wenig abzurunden. So,
das Beispiel, das sowohl ich der Reihenfolge,
sowohl ich als auch Fred, dann im zweiten Teil der Vorlesung,
womit wir uns so ein wenig beschäftigen werden, ist,
Axel Schmolitzky ist ein Freund des offenen Meeres.
Deswegen ist also das Beispiel, das er hier gewählt hat,
ist das Temperaturmessgerät in einer hochseetauglichen Boje.
Dass das Ding hochseetauglich ist, spielt für die weitere Betrachtung,
also sowas von überhaupt gar keine Rolle.
Die könnte auch auf der Alster rumdümpeln, diese Boje.
So, jetzt wissen sie alle, was eine Boje ist,
was soll die tun in unserem Fall?
Da ist so ein Sensor drin
Und er misst über den Tag immer wieder die Temperatur.
Völlig egal, in welcher Reihen, in welcher Reihenfolge schon,
aber ich wollte sagen, in welcher Taktrate der das misst.
So, leider Gottes ist es, auch wenn die so unfassbar hochseetauglich ist,
hat die einen ganz kleinen Speicher, tausend Messwerte können gespeichert werden.
Jetzt stellt sich die Frage,
wie gehen wir da mit dieser Begrenzung um und so das,
was wir wollen, ist, also die letzten tausend Messungen speichern,
hat man halt die letzten tausend gespeichert.
Das ist jetzt eine echte Entwurfsentscheidung,
die so ein Experte hier getroffen hat,
das ist das,
was uns interessiert
Wir wollen wissen, also was ist das Maximum,
das Minimum dessen, was da so an Temperaturen gespeichert worden ist.
Jetzt, das ist so die Aufgabenstellung. Vielen Dank, meine Damen und Herren.
Ich erwarte sie morgen früh um 8 Uhr mit einer Lösung.
So ungefähr geht es da in dem Berufsleben.
Ist doch kein Problem für sie, sind doch Experten.
Und dann sagen sie, klar, wir können alles.
Das haben sie ja jetzt in dieser Veranstaltung auch schon gelernt.
Also vielmehr am Rande dieser Veranstaltung,
wie sie sich in solchen Situationen zu verhalten haben. So,
und jetzt das, was ihnen sofort einfällt nach dieser Vorlesung,
dass es für die Realisierung dieser unfassbar komplexen Aufgabenstellung bietet,
ein Array an, um diese Sammlung von Messwerten zu implementieren.
Zunächst, was kann man sich überhaupt, also so unter
so einem Array vorstellen? Wir haben ja schon an der
einen oder anderen Stelle mal kurz in den Hauptspeicher geschaut.
Da werfen wir jetzt auch wieder einen Blick rein. Dieser Hauptspeicher,
der fängt irgendwo an, so an der Adresse null,
also an dieser logischen Adresse null.
Und so ein Array ist sowas wie ein,
können Sie sich jetzt erstmal vorstellen,
das ist eigentlich ein relativ tragfähige Modellvorstellung
Array ist nichts anderes als so ein Segment in diesem Hauptspeicher,
der so einzelne Zellen, das so einzelne Zellen für sich beansprucht.
Und dadurch in der Lage ist, für sie im Programm
einmal gleichartige Elemente zugreifbar zu machen. Dieser Zugriff erfolgt über einen Index,
also das hier ist das erste Element des Arrays,
dass wir zugreifen wollen, das hat den Index null.
Ich weiß nicht, wie oft sie könnten mal mitzählen,
bis zur Zahl tausend,
wie oft ich das jetzt sagen werde im Rahmen Dieser Dreiviertelstunde,
das ist der erste Array, das ist das erste Array-Element in Java,
ist immer das Element mit dem Index null.
Das ist so. Und das bleibt auch so.
Warum das so ist, darüber können wir vielleicht,
also in der letzten Vorlesung mal sprechen.
So, das, was dieses Array weiterhin kennzeichnet,
ist, dass es eine Liste mit fester Größe ist.
Also wenn sie einmal sagen,
ich hätte gerne ein Array mit fünf Elementen und sie deklarieren
sich das als Variable in einem Java-Programm,
dann bleibt das ein Array mit fünf Elementen
Es hört sich im Laufe dieses Programms, wird sich das nicht mehr verändern.
Wir werden später noch Sammlungen kennenlernen, da müssen sie nicht
sagen, wie viele Elemente soll denn diese Sammlung haben.
Und das ist diese, sind Mengen,
ist das zum Beispiel fremd, dass man denen sagt,
so wie viele Elemente sie haben sollen bei ihrer Deklaration,
bei dem Array ist das anders.
Dem Array müssten sie sagen, du seist eine Sammlung mit
fünf Elementen und dann bleibt das also. So,
und das, was, da ist ja ein Speichernahes Konzept,
ist, dass Array, nun,
das ist für für den Alltagsgebrauch eigentlich so irrelevant,
aber es wird hier ein zusammenhängender Speicherbereich,
wird für sie reserviert in dem Moment,
in dem sie ein Array deklarieren.
Das hat nachher sie so meinetwegen etwas zeitkritischere Applikationen bauen.
Ist das eine Überlegung, die eine Rolle spielen kann?
Weil diese Art von Speicherallokation ist dann auch so dem Computer,
dem Laufzeitsystem ermöglicht, also vergleichsweise schnelle Operationen durchzuführen,
ist aber so für uns, für den Hausgebrauch,
wenn es darum geht,
so die eigene Plattensammlung zu sortieren oder sowas,
Achtung,
Ist das eigentlich irrelevant. So, das ist so
die Grundidee des Arrays, der Reihe, der Reihung.
Es wird ein fester, indizierbarer Speicherbereich von gleichartigen Elementen für
sie reserviert. Da können wir jetzt was draus machen.
Da können wir also zum Beispiel dann die Temperaturen,
die unsere hochseetaugliche Boje misst, können wir darin ablegen.
So, was ist jetzt ein Array? Wir haben so elementare Datentypen kennengelernt,
also sowas wie Intager und Bojen und wir haben auch schon darüber gesprochen,
dass es also diese was komplexeren Datentypen gibt.
Und das war ihm dann eben von Ihnen selbst definierten Klassen,
die unter Verwendung von sogenannten Referenzraviablen, Ravioli, habe ich Hunger.
Nein, also die, wo die unter Verwendung von Referenzvariablen
geht, also implementiert werden. Und so ein Erry-Objekt,
wenn Sie damit umgehen, den Sie das deklarieren,
wird es auch über den Mechanismus der Referenzvariablen umgesetzt
Das heißt, wenn Sie,
jetzt sehen Sie hier schon einen Ausschnitt aus der entsprechenden Java-Syntax,
wenn Sie ein Array von Intage an deklarieren wollen,
dessen Name sei mal Int Array,
dann passiert es also in dieser Art und Weise und das,
was Sie da deklarieren,
ist eine Referenzvariable und so wie diese Notation kennen Sie ja auch schon,
so wie das hier dargestellt worden ist,
Sie haben jetzt erstmal eine entsprechendes Objekt deklariert,
aber Sie haben ihm
noch keinen Speicherbereich anuziiert
Das ist ja, kennen Sie so als Herangehensweise,
ist das ganz analog zu dem,
wenn Sie so Ihre Klasse Person geschrieben haben oder Ihre Klasse Konto,
irgendetwas Selbstdefiniertes und Sie deklarieren davon eine Variable,
dann haben Sie zunächst mal eine Referenzvariable,
deklariert aber noch keinen Speicher aluziiert,
in der das entsprechende Objekt oder für das entsprechende Objekt,
wenn es denn mal mit New angelegt worden ist.
Ganz analog ist das bei Arrays. Also hier, was Sie hier hingeschrieben,
nicht Sie, aber was ich wir hier hingeschrieben haben,
ist, also wir beabsichtigen mal ein Objekt vom Typ Array von Intager dafür Speicherplatz zu aluziieren.
Wir deklarieren erstmal die Referenzvariable in Array. Soweit so gut. So,
jetzt sehen Sie das jetzt nochmal so in der allgemeinen Java-Syntax,
dass es sie geben, eine Deklaration, eine Array-Deklaration,
das ist jetzt hier ein eindimensionales Array,
es gibt auch mehr Dimensionale, das sehen Sie dann in den Folien,
die ich jetzt hier ausgeblendet habe, ist das in aller Breite ausgeführt,
sowohl für den hiesigen Zusammenhang irrelevant.
So sieht die allgemeine Deklaration aus, intentional, extensional,
zwei Beispiele. Das hier ist ein Array von Integern.
Da heißt es also Int, gefolgt von diesen eckigen Klammern,
mit dem Namen Numbers, die Variable heißt Numbers.
Und hier ist es ein Array von Personen, die People heißt.
Diese Variable heißt People. So, also man kann Arrays von,
das habe ich ja vorhin auch gesagt,
der Elementtyp des Arrays ist immer derselbe.
Das sollte ich vielleicht anders formulieren. Es sind also Sammlungen
gleichartiger Elemente. Und bei uns ist es das eben dann
das Gleichartig, kann man da ruhig auch mit gleich
Kann man gleich, kann man auf gleich einschränken. So,
jetzt haben wir also gesehen, wie man eine solche Array-Variable deklariert.
Jetzt kommt die spannende Frage. Nun, wie erzeugt man
denn jetzt ein Array-Objekt, das also an diese Array-Variable gebunden wird?
Und das ist eigentlich im Großen und Ganzen auch vergleichbar zu dem,
was sie so als Mechanismus schon kennen.
Sie sehen das hier in der entsprechenden rot, rot gekennzeichneten Stelle.
Und man sagt halt so unter Verwendung dieses Operators New,
okay, wenn ich also einen als Int-Array deklarierte Variable mit einem Objekt versehen möchte,
dann erzeuge ich halt dieses Array-Objekt, indem ich den Operator New verwende.
Ich sage immer so, von welchem Typ soll das sein,
was da erzeugt worden werden soll als Array-Element.
Und dann, das ist jetzt der einzige Unterschied zu dem,
was sie bisher verwendet haben, muss ich dem Array-Objekt jetzt auch noch sagen,
wie viele Elemente es haben soll.
Und ich habe ja ganz am Anfang gesagt, nun,
Array-Objekte haben immer eine konstante Länge und diese Quäche länger es denn haben soll,
das schreibt man jetzt in diese eckige Klammer rein.
Das heißt, mit einer Anweisung dieser Art,
wie sie hier steht, haben wir jetzt der Array-Variablen in Array
ein Ellie-Objekt mit insgesamt acht Elementen zugewiesen, ja, zugewiesen.
Und wenn man das in eine Zeile zusammenschreiben will,
dann schreibt man das halt so in der Form,
wie das da unten in Blau drunter steht.
Dieses, diese Zeile hier erzeugt jetzt, also unter dem
Namen Int-Array, verfügbar ein Array-Objekt mit insgesamt acht Elementen.
Jetzt kommt der Lacmust-Test für die Konsistenz dieser Folie.
1, 2, 3, 4, 5,
6, 7, 8. Stimmt.
Yes. So,
hat er geschafft
So, und jetzt können wir auf dieses In-Array zugreifen.
So, bevor wir das tun, ist die Frage,
wie immer, wenn man also eine Variable deklariert,
was ist eigentlich der Standardwert für das, was man da an Objekt erzeugt.
So, und da gilt eigentlich genau das Gleiche,
wie das, was also für die Basistypen gilt,
wenn sie einen Array von Integern erzeugen,
dann kriegen die Integer-Elemente des Arrays, kriegen den Wert,
null, Buliens kriegen den Wert
Falls, Referenztypen den Wert null.
Das heißt, da steckt nichts drin
Nichts kann man nicht sagen, weil nichts gibt es nicht
in diesem Fall. Das stecken also die Default-Werte drin.
Das ist, glaube ich, die bessere Formulierung. So,
sie können auch gleich, das sind jetzt aber alles so Kurzschreibweisen,
die im Alltag eher eine untergeordnete Rolle spielen,
wenn sie das so hinschreiben, dann sind hier so Standard,
dann sind die default-Werte für die einzelnen Array-Elemente,
werden halt so belegt.
Okay, dann können sie dann haben mit dieser Art der Kurzschreibweise
so eine Form, also wenn sie den wollen,
auch spezifische, spezielle Werte bei der Deklaration gleich zu notieren.
Hier steht jetzt tückischerweise, also die stehen die Werte, eins bis acht drin.
Jetzt sage ich es also mindestens zum dritten Mal,
wenn man auf dieses Element zugreifen will,
das ist nicht zu verwechseln mit dem Index hier.
Die Zelle mit dem Index null hat den Wert eins und
die Zelle mit dem Index 7 hat den Wert acht
Kriegen sie das, was Fred schon an der
einen oder anderen Stelle auch schon mal gesagt hat,
dass dieses Off-By-One-Problem ist beim Umgang mit Aris extrem beliebt.
Jetzt kommen wir zur Indizierung und wieder sagt er es,
Aris werden beginnt bei null indiziert.
So wie, wenn ich jetzt so häufig sage,
ja wie greife ich denn jetzt endlich mal auf diese erste Stelle zu?
Und das sehen sie jetzt hier. Wir haben jetzt
eine Array-Variable namens Tempridges deklariert. Wir wollten ja schließlich Temperaturen
messen und wenn sie auf das erste Element zugreifen wollen,
dann geschieht es in dieser Art
Und Weise. Die Referenzvariable heiße Tempridges und das erste Element,
dieses Arrays Tempridges von Intagem. Intage an,
das sind wahrscheinlich keine Intager, die hier drin stehen.
Das ist irgendwas, was man mit Temperaturen,
also so sind das wahrscheinlich Reels oder Floats, sowas von der Art.
Wenn sie auf dieses erste Element zugreifen wollen,
dann ist das halt in eckigen Klammern, Namen der Referenzvariable,
eckige Klammer und null ist das erste Element und folgend ist dann,
also greifen sie auf die weiteren Elemente mit höheren Indizes,
greifen sie auf die weiteren Elemente zu
So, und demzufolge hat also ein Eri der Größe 8,
wie in unserem Beispiel oder 1000,
hat es als gültige Intercess 0 bis 7 beziehungsweise 0 bis 999.
So greift man lesend auf ein Array-Element zu. Wenn man Lesen zugreifen will,
möchte man vorher möglicherweise auch mal was geschrieben haben.
Und hier sehen Sie, wie also dieses Zusammenspiel zwischen Lesenden und schreibenden Zugriff,
wie man das hinschreiben kann. Also nehmen wir mal so den Float-Element,
das, was wir gerade bearbeiten wollen,
womit wir wir irgendwas machen wollen, zum Beispiel OP feststellen wollen,
ob es das Minimum oder das Maximum ist,
da lassen wir uns lesen, also von der Stelle,
von der ersten Stelle ist Arrays den Wert geben,
wir greifen,
lesen halt so in dieser Art und Weise darauf zu und schreibend dann auf diese Art und Weise.
Das, denke ich, ist eigentlich alles ganz so,
da steckt noch überhaupt gar kein Mysterium drin,
wie man also auf Elemente der Sammlungen zugreifen kann.
So, etwas spannender wird es dann in dem Moment,
Wenn wir uns mal Gedanken darüber machen,
was passiert denn jetzt eigentlich,
wenn in so einem Array nicht Werte von elementaren Datentypen drin sind,
sondern Werte von Referenztypen enthalten sind.
So zunächst mal so die Modellvorstellung gegeneinander gehalten.
Hier oben sehen sie also jetzt so ein Array von Floats,
wie wir gerade gesehen haben. Und da stecken ja in
den einzelnen Hauptspeicher-Elementen in den einzelnen Array-Elementen Werte drin.
So diese Werte, auf die kann man eben als Floats
in dem Moment, das sind Floats und die sind
elementare Datentypen
So, wenn das ein Array von Personen ist,
wir sollen uns daran hindern, also auch ein Array von Personen
zu deklarieren und zu initialisieren und mit Werten zu belegen,
dann stecken da eben keine elementaren Datentypen oder Werte von elementaren Datentypen drin,
sondern da stecken Referenzen drin.
Boah. Das ist mein Schreibtisch. Das ist kein Array,
das ist eine Menge. Es gibt Leute, die behaupten,
es ist eine Müllkippe, aber es ist auch... Keine Ahnung.
So, zurück zum Thema. Ein Array von Personen bedeutet also,
wenn man sich das nochmal so als Hauptspeichermodell versucht vorzustellen,
ist es ein Array von Referenzen auf Personen, Objekte in diesem Fall.
Das ist also, irgendwie haben wir es geschafft,
in dieses Array-Element 1, eine Referenz auf ein Personenobjekt hineinzubekommen.
Das ist nicht schwierig, weil also so, sie haben
den Lesenden und schreibenden Zugriff auf Elemente ja schon gesehen.
Und ob sie da jetzt einen Intager,
einen Float oder eine Variable von einem Referenztyp,
wie in diesem Fall einer Person hineinstecken, beim Schreibenden Zugriff ist eigentlich egal.
Das ist nicht nur eigentlich egal, das ist vom Mechanismus
her, ist das so genau dasselbe
Das ist also so, ist das nur so von der Modellvorstellung her,
ist das jetzt so etwas erweitert,
weil eben hier nicht mehr Werte von elementaren Datentypen drinstecken,
sondern Werte von Referenztypen.
Das spielt so im Alltäglichen Umgang, solange man es nur mit
einem Array zu tun hat, macht es auch eigentlich keinen Unterschied.
Wir werden gleich mal uns die Frage stellen,
was passiert eigentlich, wenn man ein Array duplizieren möchte?
Wie kann man sich das denn dann vorstellen, was passiert da eigentlich?
Da wird es schon etwas interessanter. So,
kurz noch, bevor wir auf diese Fragestellung eingehen,
Ist jetzt hier eine Fehlermeldung, die sie wahrscheinlich,
der sie häufiger begegnen werden, als ihnen lieb ist,
wenn sie auf einen ungültigen Index zugreifen wollen.
Und ungültige Indizes sind also alles, was negativ ist.
Und alles, was über die Länge eines Arrays hinausgeht,
das ist ja mein Array von acht Elementen, erzeugt,
ein Objekt von acht Elementen,
ein Array-Objekt von acht Elementen erzeugt und denken,
so ohne weiter drüber denken
Um und weiter darüber nachzudenken, okay,
ich möchte mal auf das letzte Element zugreifen,
schreiben da also Tempbridges von 8 hin und dann sagt es Array out of bounds Exception.
Also das kann ich auch ziemlich flüssig sprechen, weil ich
das eben auch häufiger gesehen habe, weil es mir lieb ist.
So, das ist dann eben so,
weil der letzte zugreifbare Index für ein Array von 8 Elementen
ist halt das Element, mit der laufenden Nummer 7,
wie man ja auch hier an dieser Darstellung schön sehen kann.
So, also die 8, 9, 10,
alles andere als 0 bis 7 sind ungültige Indizes für
dieses Array
Das, was auch häufiger passiert, ist so,
dass die Fehlermeldung haben sie möglicherweise auch schon gesehen,
eben wenn sie Referenzvariablen nur deklariert haben,
aber nicht ein Objekt erzeugt haben, das mit dieser Referenzvariablen verbunden ist.
Dann kriegen sie eine sogenannte Null-Pointer-Acception,
die wird ihnen auch im Umgang mit RAS-Licht erspart bleiben,
wenn sie nur ein RAI-Objekt deklarieren, aber vergessen,
es zu erzeugen und gleich versuchen, einen schreibenden Zugriff auf ein Element,
nämlich das erste Element zu machen, dann kriegen sie eine Null-Pointe-Acception,
weil an dieser RA-Varia an diese RA-Variablen noch kein Objekt gebunden ist.
Warum sollte es, also, ja,
das ist dann so, an dieser Stelle verhält sich also,
dass RA genauso wie ein, in Anführungsstrichen, normales,
normales Objekt.
So, jetzt geht's, gehen wir noch einen Schritt weiter.
Jetzt gehen, gerade haben wir gesehen, was passiert,
wenn man da so auf ein Array-Objekt von Intagern versucht,
einen Zugriff zu machen,
das noch nicht existiert
Jetzt geben wir insofern einen Schritt weiter,
als dass wir jetzt hier mal ein RA von Konnten erzeugen.
So würde man das Ende dann hinschreiben.
Also RA, Element-Typ, Konto, es heißt Konten.
Und wir weisen dem gleich auch, also wir aluzieren
gleich auch das Objekt, es soll vier Elemente haben.
Und diese Schreibweise hier ist jetzt möglicherweise etwas gewöhnungsbedürftig.
Oder könnte man, könnte Fred jetzt wahrscheinlich noch ein Stündchen
drüber sprechen, was also so mit dem Operator Präzedenzen
hier los ist
So für uns, von der Straße.
Wie liest sich das? Nun, ich möchte mit dem,
was ich referenziere, wenn ich sage, konnten von null.
Das ist ja ein Kontoobjekt. So, auf das möchte ich
die Operation einzahlen ausführen. Und zwar mit dem Parameter 123
, was auch immer. Da würde man ja denken,
das ist eigentlich eine ganz normale Operation, beziehungsweise es müsste eigentlich klargehen.
Und das würde es auch tun, wenn,
also an der Stelle konnten von null bereits ein Kontoobjekt hinterlegt wäre,
eine Referenz auf ein Kontoobjekt. So wie der Code hier steht,
es ist aber ein bisschen voreilig, also weil zwischen dieser Zeile,
ich lege jetzt dieses Objekt RA von Contenan mit vier Elementen und dem Vorgang,
ich möchte an der Stelle,
wo ich eigentlich eine Referenz auf ein Kontoobjekt erwarte,
möchte ich jetzt schon was einzahlen, da ist aber noch nichts.
Da steht nämlich im Moment noch eine leere Referenz drin,
also ein Nullpointer und deswegen kriege ich hier auch eine,
an der Stelle, wenn sie den Code so ausführt,
kriegen sie genau das, was hier steht, nämlich eine Null-Pointer-Exception.
Das, was also dazwischen noch passieren müsste, ist,
dass man an die, mindestens an der Stelle konnten von null,
müsste man mal noch tatsächlich eine Referenz auf ein echtes Kontenobjekt einführen,
bevor man diese Operation konnten, null, die referenziert ein Kontenobjekt,
bevor man an diesem Kontenobjekt die Operation einzahlen, aufrufen kann.
Das ist jetzt so eine der Stellen,
wo so das Wunder der Objektorientierung Mal wieder uns zuteilen wird,
weil Konten von null d-referenziert ja ein Objekt.
Und auf diesem Objekt kann ich eine Operation,
die in der Klasse definiert ist für dieses Objekt,
kann ich die aufrufen in dem Fall, also einzahlen.
Sie haben schon verschiedene Arten von Schleifen kennengelernt und
das Array und die Vorschleife sind zwei Seiten einer Medaille.
Die Vorschleife wurde, ist ja so das Mittel der Wahl,
wenn man über eine fest, wenn man weiß,
wie viele Schleifendurchläufe möchte ich denn eigentlich durchführen
Und wenn das Array eine Sammlung von gleichartigen Elementen mit fester Größe,
also unveränderlicher Größe ist, dann ist der Gedanke ja naheliegend.
Also, dass diese beiden Programmiersprachenkonstrukte sehr eng miteinander und gut zusammenpassen.
Und jetzt sehen Sie hier ein Beispiel dafür, wie das verwendet werden kann.
Also so an hier diese Operation Print Array,
an die wird als Parameter ein Array von Intagern übergeben.
Und da iteriert man jetzt also munter über diesem Array,
in dem man bis zu der Stelle Array.let in,
also in-arry.lanks kommt, um jedes einzelne Element zu erwischen.
Da braucht man jetzt keine Wildschleife vor oder mit unserem Preject oder Post-Ject
, das braucht man alles nicht. Man weiß ja,
wie lang das Ding ist und das weiß man,
indem man die Operation lenkt an dem RA aufruft.
Das sehen Sie hier in Rot. Herr Gott Sacker,
das sehen Sie hier. Und jetzt gucken Sie da drauf
und ich vermute mal, dass also 98 Prozent von Ihnen
denken jetzt, da ist was faul an der Stelle
Das klappt doch so nicht. Das wird doch so nie
übersetzt. Oder doch? Und es wird übersetzt. Und
es läuft sogar. Da bin ich mir ganz sicher.
Und warum das so ist? Das wird in Fred ab
circa 3 Uhr erläutern. Für diejenigen,
die jetzt im Moment nur so ein ungutes Gefühl im Bauch
haben,
also warum läuft das
Da fehlt doch was. Ja, das, was,
also ich jetzt mindestens auch mal denken würde, so,
wenn ich jetzt sie wäre, naja,
hier müsste eigentlich noch Klammer auf, Klammer zustehen, weil,
also was will man denn jetzt an so einem Array aufrufen,
außer, dass da jetzt so, Klammer auf, Klammer zu, also eine Operation, die einen Intager liefert.
So, und dass das nicht sein muss, Fred.
Das ist jetzt so ein dramaturgisches Mittel. Ich versuche den
Spannungsbogen in der Vorlesung aufrechtzuerhalten. Nicht, dass ich nicht glauben würde,
dass sie sich sowieso schon auf Fred freuen,
aber das wird er ihnen dann auch noch erzählen.
So, Ich habe schon davon gesprochen,
wir werden so die etwas interessanteren Fragen im Umgang mit Arrays,
also sind so, wir haben festgehalten,
Array-Variablen sind Referenzvariablen und jetzt das Kopieren von Referenzobjekten von Variablen.
Also ist da ja, es ist ein, sagen wir mal,
technisch gesehen ist das eigentlich kein allzu großes Problem.
Im Alltag, im Programmieralltag macht es immer wieder,
also ungeahnte Freude, sich mit der Frage zu beschäftigen.
Und ich erkläre Ihnen jetzt mal, warum das so ist,
warum Sie immer wieder Effekte erzielen, die nicht erwartungskonform sind.
Wir haben ja so ein Int-Array,
wir deklarieren das und weisen dem auch gleich ein Objekt zu und dieses Objekt habe dann,
also den Element-Typ Integer und die Werte 1, 2,
3. Soweit, so gut.
Das heißt also, wir haben so eine Struktur jetzt
geschaffen,
diese Struktur
Und jetzt deklarieren wir uns noch ein zweites Intager-RA-Objekt,
nämlich Int-RA2. Und dem sagen wir,
wir weisen dir den Wert von Int-RA1 zu.
Durch diese Zuweisung hier. Diese Zuweisung kann jetzt,
wenn man da einfach mal so draufschaut, kann hier unterschiedliche Effekte haben.
Die könnte ja die Bedeutung haben, nimm das,
worauf int-RA1 verweist, leg ein neues Objekt an und kopiere alles,
worauf int-RA1 verweist,
in das,
worauf jetzt
auch int-RA2 verweisen soll
Das fände ich eine spontan legitime Interpretation.
Ist es aber nicht. Was da passiert, ist,
es ist viel einfacher. Es wird jetzt, also un-in-RA2
, wird der Wert von in-RA1 zugewiesen.
Und der Wert von in-RA1 ist eine Referenz auf dieses Objekt.
Und jetzt haben wir zwei Referenzen auf dasselbe Objekt,
nämlich das hier
Mit beiden Referenzen können wir jetzt auf diesem Objekt lesend und schreibend zugreifen.
Was lassen Sie sich jetzt noch mal so langsam durch den Kopf gehen,
dass das so ist und dass also eine solche Zuweisung,
wie sie hier steht,
nicht etwa bedeutet,
dass das referenzierte Objekt dupliziert wird,
wie man das also bei den Zuweisungen von Werttypen kennt,
sondern dass es hier funktioniert
wie bei den Zuweisungen von Referenztypen
Sodass nur die Referenz kopiert wird. Nicht aber das referenzierte.
Und in diesem Sinne und nicht nur in diesem Sinne,
sondern also genau deshalb ist es so richtig, wie das hier steht.
Beide Referenzen verweisen auf dasselbe Array-Objekt. So, jetzt,
wenn man tatsächlich eine Kopie haben möchte, dann muss man
sich halt ein neues RAy-Objekt erzeugen und dann elementweise die elementweise die Elemente kopieren.
Ersatzweise die Operation Clone verwenden
Und das hört sich jetzt so an wie,
ach so, ja, dann mache ich das halt.
Jetzt stellen wir uns bloß die nächste Frage,
das habe ich jetzt auf einer Folie nicht weiter, nicht weiter ausgemalt.
Wenn hier jetzt nicht Elemente, Elemente von Werttypen drinstecken,
sondern Elemente von Referenztypen, also Referenzvariablen,
dann kann man sich als nächste Frage stellen,
was bedeutet denn Clone, bedeutet Clone, dass dann,
also die Elemente, kopiert werden oder bedeutet das,
dass die Referenzen der Elemente, die in dem RA drin enthalten sind,
ob die mitverfolgt werden?
Das ist dann eine sogenannte Deep Clone. Und damit das,
was ich jetzt sage, nicht im Internet erscheint,
Ja, das möchte der Lied kein Mensch,
dass das jetzt im Internet rein einer deutschen Hochschule so ein Wort verwendet wird.
Und ich zähle jetzt auf Sie, dass also das,
was ich jetzt hier sage, das ist dasselbe,
nach demselben Prinzip verfährt, wie Weihnachtsfeiern,
was auf der Weihnachtsfeier war, bleibt auf der Weihnachtsfeier.
So, also Clone und Deep Clone,
das können Sie sich dann auch nochmal zu Gemüte führen.
So, hier sehen Sie jetzt nochmal so für Hobsella
Für den Zusammenhang, also des Kopierens, die naheliegende Verwandtschaft
von Arrays und Vorschleifen. Das heiratet sich sehr gut und
sie kriegen auch noch so von Fred möglicherweise eine,
es gibt noch eine Kurzvariante der Vorschleife,
um einfach den Programmieralltag noch ein klein wenig zu vereinfachen.
So, jetzt gehe ich
so langsam in die Zielgrade,
was Arrays anbetrifft
Über den Index, man hat elementweise auf so eine Reihung zugreifen.
Das ist häufig ein, es ist häufig ein, das will man häufig.
Also wir werden noch uns im Rahmen von SE1 2
werden wir uns auch noch übersuchen und sortieren unterhalten.
Und es gibt so Verfahren, die Suchs, Suchverfahren,
die stark davon abhängen, dass man auf so Sammlungen,
dass man da in die Indexweise drauf zugreifen kann.
Und dafür bieten sich dann eben Arrays als Datenstruktur,
bieten die sich an
Was ich schon ganz am Anfang auch gesagt habe, das Kopieren eines ganzen Arrays,
kann also sehr effizient, so vom Laufzeitsystem auf unterliegende Maschinenbefehle abgebildet werden.
Das heißt also, immer wenn, also wenn es so ein Performance geht,
ist das Array eigentlich nicht, ich will nicht sagen unschlagbar,
aber ist das zunächst mal eine naheliegende Implementenentwurfs- und Implementationsentscheidung.
So, Nachteile Wir haben darüber gesprochen, also diese feste Größe, muss man halt sein Problem. Ich weiß nicht,
ob das jetzt ein Nachteil ist,
aber wenn man ein Problem hat, das davon lebt,
in Anführungsstrichen, dass so die Sammlung,
mit der man es zu tun hat,
eine dynamische Größe hat, dann kann man,
dann ist Array möglicherweise nicht die erste Wahl,
weil man hat ja eigentlich dann nur die Chance,
okay, wenn ich nicht weiß,
wie viele Elemente drin sein werden,
dann nehme ich als Größe erstmal eine Milliarde,
weil dann passt es schon rein
So wenn man genug Speicher hat, also wenn man nicht gerade
eine hochseetaugliche Boje mit so einem ganz kleinen Speicher hat,
also dann kann man das machen.
Ansonsten sollte man eine andere Datenstruktur wählen. Aber das ist so,
das wird eher ein Berufsalltag, ihren Programmieralltag prägen,
dass sie ständig solch Entwurfsentscheidungen treffen und dazu eine dieser Entwurfsentscheidungen ist dann sehr häufig,
was ist eine adäquate, zugrunde liegende Datenstruktur,
um mein Problem zu lösen.
So hier ist jetzt noch Wir sehen jetzt,
hier sehen Sie noch eine Abkürzung, die Sie möglicherweise noch nie gesehen haben.
Das ist das Java-Collection-Framework. Also es gibt im Java
in der Umgebung der Programmiersprache gibt es ein sogenanntes Collection-Framework.
Also es gibt jede Menge Frameworks für jede Menge Fragestellungen.
Und das Collectrum-Framework ist, also ist in Anführungsstrichen sehr beliebt,
weil also der Umgang mit Sammlungen,
also die entsprechende Sammlung für ein Problem,
also die zu finden,
also da gibt es eigentlich alles,
also sie brauchen
keine Sammlung selbst
zu implementieren
Da werden sie auch noch Sammlungen kennenlernen, die höherwertige,
sogenannte, höherwertige Operation beinhalten.
Also man kann ein Array, so jedenfalls standardmäßig nicht,
danach fragen, ob ein bestimmtes Element in ihm drin ist.
Will man manchmal wissen. Also ist ein Element schon in
einer Menge, in einer Sammlung enthalten. Diese Sachen müssen sie
sich unter Verwendung des Arrays als zugrunde liegender Datenstruktur selbst schreiben.
So, jetzt noch zwei, drei Worte zu Klassen und Objekten.
Das werde ich jetzt vergleichsweise kurz machen
Wir haben ja jetzt so eigentlich ein einfaches zugrunde, ein einfaches Programmiermodell.
Wir schreiben Klassen, was sind Klassen, statischer Programmtext,
okay. Während des Programms läuft, können wir Objekte von
genau diesen Klassen erzeugen. Das ist soweit so gut.
Das ist ein einfaches Modell. Die Frage,
die wir jetzt noch kurz oder ich mit Ihnen noch kurz besprechen möchte,
ist, und was jetzt mit den Klassen selbst,
kann ich auf die zur Laufzeit eines Programms zugreifen
Und wenn ja, warum? Wieso sollte ich das tun wollen? Ich meine,
das mussten sie bis jetzt ja auch nicht, oder?
Ja, das denken sie, dass sie das nicht wussten.
Sie haben es getan, ohne dass sie es wissen.
Und wir werden ihnen jetzt noch mal zeigen, warum das sinnvoll ist,
auch Klassen zur Laufzeit eines Programms selbst so handhaben zu können.
So, jetzt gucken wir uns mal an,
so das zugrunde liegende, sie werden hoffentlich so in ihrem Studium
dann auch noch mal so Veranstaltungen wie Compilerbau oder Programmiersprachen besuchen.
Da gibt es, also die Welt ist da Unfassbar,
vielfältig in dem Bereich,
ist hier nur so ein ganz kleiner Teaser eigentlich,
mit dem wir sie hier beschäftigen wollen.
So, Klassenobjekte, das ist jetzt erstmal ein neuer Begriff,
sind in laufenden Java-Programmen zugreifbar. So,
sie existieren und wir machen das jetzt erstmal so am Beispiel,
bevor ich da jetzt gleich näher drauf eingehe,
wie das also prinzipiell funktioniert.
Sie sehen jetzt mal hier wieder unsere gute alte Klasse
Konto und die beinhaltet jetzt von der Syntax etwas,
was sie noch nicht gesehen haben
Es ist je rot dargestellt. Da steht nämlich Static.
Und die Bedeutung dieses Schlüsselwortes ist, alles,
was dahinter steht in diesem Fall, also die Exemplarvariar,
ich sage jetzt, ein Tag wird nicht Exemplarvariar,
die variable Exemplarzähler, die existiert genau einmal pro Klasse.
Also nicht, wie sie das bisher kennen,
also pro Objekt,
sondern einmal pro Klasse
Das ist neu. Das ist anders. Und genauso ist das jetzt mit so,
das gilt, das kann man jetzt mit Static,
kann man das nicht nur für exempir Variablen machen.
Man kann das auch für Operationen machen. Die Operation,
Anzahl erzeugte Exemplare, dadurch, dass sie statisch deklariert ist,
die existiert in dieser Klasse Konto, auch nur genau einmal.
Und zeige ich Ihnen mal, wozu man das verwenden kann.
Jetzt können Sie hier an dem Kontenverwalter sehen.
Und das ist,
oh Gott
Da war noch keiner aufgeräumt. So, die Klasse konnten Verwalter,
die ruft nämlich jetzt an der Klasse Konto an der Klasse Konto,
ruft sie die Operation, Anzahl erzeugte Exemplare auf. Und das ist jetzt so,
wenn sie die Implementation jetzt nochmal sich so hier vor Augen führen,
in eine im Objekt, also in dem Konstruktor eines Objektes der Klasse Konto,
wird der Exemplarzähler, das ist die hier deklavierte Klassenvariable, eins erhöht.
Und deswegen kann man also auch über diese Operation,
Anzahl erzeugte Exemplare, die genau einmal existiert in der Klasse Konto,
sich die Gesamtanzahl der Konten unter der Voraussetzung,
dass jedes Objekt von der Klasse Konto, das erzeugt wird,
der Konstruktor einmal ausgeführt wird und dann also diese Klassenvariable um eins erhöht wird,
kann man sich also an der Stelle,
oder das kann man sich auf diese Art und Weise,
so wie das hier steht, kann man sich erzählen lassen,
wie viel Kontenobjekte es denn überhaupt gibt.
Und diesen Mechanismus Also es gibt nicht allzu viele Stellen,
so an denen man, also diesen Mechanismus sinnvoll anwendet.
Das muss man, aber das lernen sie dann später bei Softwaretechnik,
so warum das also ein extrem gefährliches Konstrukt ist.
Wir zeigen ihnen, dass jetzt mit den Klassenvariablen und den Klassenoperationen,
damit sie verstehen, was sie eigentlich hier hinschreiben,
wenn sie das Java-Programm schreiben, dass sie immer schreiben,
dass es nämlich so losgeht, Public Static Voidmain.
Das können sie ja wahrscheinlich nachts um drei unter Einfluss oder
auch bitte ohne Einfluss von Drogen.
Können Sie ja die erste Teile eines Java-Programms auswendig hersagen.
So, und jetzt wissen Sie, warum da steht Static
World Main. Und das ist nämlich eine Operation,
die muss genau so deklariert sein, damit das Laufzeitsystem weiß,
in Anführungsstrichen, hier soll dieses Java-Programm losgehen.
Das ist für mich der Startpunkt. So, der Einstiegspunkt für jedes Java-Programm.
Sie wissen ja, wenn Sie Ihre normalen Klassen schreiben,
Die haben ja jetzt mit Blick auf das Laufzeitsystem keinen Anfang und kein Ende.
Die sind ja einfach da. Da kann man Objekte davon erzeugen,
aber hey, wo soll der Ganze, die ganze Party den Verzeihungen, den eigentlich losgehen?
Und das ist jetzt also über diese Klassenoperation,
die genau einmal da ist, ist es jetzt hoffentlich deutlich,
da muss kein Objekt erzeugt werden, sondern dadurch,
dass das eine statische Klassenoperation ist, braucht sie keinem Objekt zugeordnet werden,
die ist also da und genau so, wie sie hier steht,
also kein Rückgabewert und sie heißt Main und sie hat diesen Liste von Strings als Parameter,
ist das der Einstiegspunkt für ein Java-Programm.
So, jetzt bin ich schon über der Zeit,
ein Mysterium, Fred wird Ihnen die weiteren Mysterien noch erläutern.
Jetzt können Sie sich auch erklären, also wie diese Anweisung,
wie das denn hier überhaupt jetzt zu verstehen ist, ja,
schreiben das, können das hier so auf der lexikalischen Ebene,
kann man das jetzt so hinschreiben, bloß was das bedeutet,
aha, es gibt also eine klasse System
Und an der, hier fehlen ja interessanterweise auch,
also so Klammer auf, Klammer zu,
da gibt es nicht eine öffentliche Klassenvariable, sondern eine öffentliche Klassenkonstante.
Und die heißt Out. So, die ist vom Typ
Prince Stream. Und die hält eine Referenz auf ein Exemplar
eben genau eines Prince Streams. Und dieser Prince Stream,
der ist in der Lage, Zeichenströme auf der Oberfläche,
also auf ihrem Terminal, auszugeben. Und jetzt haben sie,
also von Public Static Volt Main bis zu System Out Printland,
Also haben sie jetzt, glaube ich,
jetzt haben wir ziemlich viel von den Sachen,
die sie möglicherweise noch mit einem komischen Bauchgefühl verwendet haben,
haben wir jetzt entmystifiziert.
Und jetzt können sie verstehen,
also wie das funktioniert und mit diesen Worten übergebe ich jetzt
an Fred und wie sonst auch wünsche ich ihnen jetzt schon
ein schönes Wochenende und wir sehen uns nächsten Mittwoch hoffentlich wieder
So, oh, ich bin ganz schön laut, oder?
Ist es zu laut, weil ich mir irgendwas runterregeln oder
das Mikrofon weiter wegnehme? Nee, ist okay. Gut,
wenn es anfängt zu piepen, mache ich es einfach irgendwo wieder leiser.
Also, Guido hatte ja schon versprochen,
dass ich euch irgendwas erzählen soll über diese Magie von Everys.
Da habe ich gerade mal so ein bisschen was zusammengebastelt.
Dass man auf Aris einfach so mit längs zugreifen kann,
das ist ja irgendwie so ein bisschen strange.
Vielleicht erstmal so ein bisschen interaktiv
Die ersten Erfahrungen mit Erics sammeln, wo muss man
Eric erzeugen, wo man uns ein Irre erzeugen.
Oder ich mache es vielleicht erst mal so. Ja,
okay, ich weiß nicht, was diese Warnung jetzt soll.
Ich will einfach mal so ein paar beliebte Fehler einfach mal machen,
dass sie es immer seht. Also mich interessiert,
welcher Wert steht eigentlich in diesem Area anstelle null?
Wahrscheinlich keiner. Nö, da gibt es eine Acception.
Und das ist genau einer der Fehler, die Guido gesagt hatte.
Also, wenn ihr eine Variable deklariert von einem Area-Typ,
dann ist das eine Referenzvariable. Also die Variable A kann
auf RS verweisen, wo Inst drin stehen.
Aber wir haben so eine Area noch gar nicht erzeugt.
Wollen wir so ein Area erzeugen
Also, nehmen wir doch mal vielleicht zehn Innenzwillig haben.
So, jetzt frage ich nochmal, was steht denn anstelle null?
Da steht die null. Sehr schön. Und anstelle eins steht die auch.
Also, da stehen jetzt überall Null. Und ich gucke mal,
ob man sich nicht auch diese Referenz mal irgendwie... Ich
würde sie mir irgendwie ganz gerne mal hier so rüberziehen.
Kann man das irgendwie machen? Ah, jetzt darf ich
dem noch einen Namen geben, das ist mir egal.
Ja, man kann sich also auch RS hier unten anzeigen lassen,
nicht nur Exemplare von Klassen. Können wir mal raufklicken.
Und jetzt seht ihr, wie so ein REM-Speicher aussieht. Also,
erstes, ist hier diese Exemplarkonstanto, nennen wir sie,
Lenks, wo also quasi der Wert,
den ich bei der Erzeugung hier angegeben hatte,
diese zehn, die wird hier vermerkt,
falls man sich später irgendwann mal interessiert,
wie lange das Eri ist.
Und anschließend stehen dann zehn in Zahlen hier drin,
so schön miteinander von null bis neun.
Finde ich also irgendwie ganz anschaulich in dem Budget.
Okay, kann man das jetzt auch irgendwie hier so stehen
lassen und mal versuchen, das Eri zu ändern?
Gut, ich will das richtig komplett sehen.
Kann ich jetzt zum Beispiel sagen,
A an der Stelle null soll den WR 42 kriegen
Oder brauchst du einen Semi-Kohlen? Nee, brauche ich nicht.
Seht ihr, dass es sich jetzt hier geändert hat?
Ich habe also jetzt hier an der Stelle 0,
habe ich den WR42 abgelegt und jetzt kann ich noch mal an Stelle 9,
lege ich die 97 ab,
wollen wir hier so ein bisschen runterscrollen, sehen,
wie das hier jetzt ist.
Und wenn ich jetzt versuche, anstelle 10 was abzulegen,
könnte man ja denken, ich habe ja zehn Elemente, dann knallt es wieder.
Es gibt in einem RR der Länge 10 gibt es nicht die Position 10,
sondern nur die Position 0 bis 9. Okay,
das finde ich irgendwie so ganz nett, so ganz anschaulich.
Und ich kann das RR auch tatsächlich fragen,
wie lange es ist. Ich kann nur so sagen,
wie lange ist es denn?
Okay. So, warum kann ich das machen?
Jetzt habe ich so ein Mini-Projekt gebaut und ich habe einfach
mal eine Klasse gebaut, die auch so eine längste,
oh, ich habe sie gar nicht konstant gemacht,
das ist aber eigentlich egal, ich mache sie mal kurz konstant.
Ah, nicht, nee, dann baue ich Konstrukte schreiben,
das will ich alles nicht.
Also ich habe hier also eine Exemplar-Variable längs.
Okay. Und jetzt habe ich mal versucht,
ein Projekt zu schreiben, sowas werdet ihr wahrscheinlich niemals brauchen.
Man kann Objekte zur Laufzeit zum Beispiel fragen,
von welcher Klasse sie sind.
Wir konzentrieren uns jetzt mal hier auf diese Methode
Also, ich übergebe irgendein Objekt X,
das kann RA sein oder irgendwie ein Exemplar an der Klasse,
die ich selbst geschrieben habe und an Stringen,
im Prinzip alles Mögliche.
Und ich frage jetzt an dieser Stelle Liebesobjekt X,
sag mal, was ist eigentlich deine Klasse?
Zu welcher Klasse gehörst du? Und dann gebe ich einfach so
einen schönen sinnvollen Text auf die Konsole aus. Also,
dass ich einfach sehen kann, folgende Klasse hat folgende Fields,
also das, was wir Exemplarvariablen oder Exemplarkonstanten manchmal nennen.
Das heißt im Englischen meistens Fields. Wir sagen auch manchmal
Zustandsfelder, oder? Ja, dann passt das ganz gut.
Okay. Und hier ist jetzt der spannende Punkt
Wenn ich also so eine Klasse an der Hand habe,
kann ich sagen, gib mir doch mal alle deine Felder.
Okay. Und was gibt mir dieses Getfield zurück?
Es gibt mir ein R von Field Objekten zurück.
Es gibt also hier in der Standardbibliothek von Java im Paket Reflect.
Gibt es alle möglichen Klassen, die so für Java-Bausteine stehen?
Felder, Methoden, Klassen, Objekte, Variablen, Parameter.
Also ihr könnt eine Klasse, alles Mögliche fragen.
Ich kann zum Beispiel fragen, was die Felder sind in Kirchen
R von Feld Objekten zurück. Und wir hatten,
glaube ich, schon letztes Jahr gesehen,
Als wir über Verzeichnungswanderer, Rekursion und so geredet hatten,
dass man über einen RM mit der erweiterten Vorschleife iterieren kann.
Also hierüber will ich iterieren, das ist mein RA.
Das ist der Typ des RAS und das ist einfach ein
völlig beliebig gewählter Name von mir,
dass ich im Schleifenrum auf das jeweilige aktuelle Moment zugreifen kann.
So, und ich mache nichts Besonderes, ich gebe es
einfach nur auf die Konsole aus. Also nochmal zusammengefasst,
ich kriege ein Objekt rein, ich frage das Objekt,
was ist deine Klasse und dann frage ich die Klasse,
gib mir mal alle deine Felder und die schreibe ich auf die Konsole.
So, und wo benutze ich jetzt dieses Printfields?
Das benutze ich zweimal in der Mainmethode
Also, einmal erzeuge ich mir so ein Wire-Objekt.
Ihr seht ja hier unten noch, Wire hat ja so
eine öffentliche Links, so ein öffentliches Längsfeld.
Und einmal übergebe ich dieses Arcs-Erre,
Justus Arcs-Erre hat man einfach bei Maine immer.
Können wir gleich noch sehen, warum man das hat.
Das ist einfach ein String-Erry. Okay,
das sieht man ja hier an der Deklaration.
Gut. Und wenn wir das jetzt mal ausführen,
dass ihr alles seht, ja.
Wo es
die Main-Methode hier ist hier
Passiert jetzt hoffentlich was Spannendes. Okay. Also er hat festgestellt,
dass die Klasse Wire folgende Zustandsfelder hat, einen öffentlichen Int namens Lenks.
Das ist genau hier dieses Zustandsfeld. Okay. Und die
Klasse Buch, was ist das denn? Also RAE,
ja, Klassen, in Anführungsstrichen, heißen irgendwie ganz komisch.
Also die heißen eckige Klammer auf. Ich glaube,
das L steht für Referenz, bin mir nicht 100 Prozent sicher.
Und dann, was der Elementtyp des RAEs ist.
Und dann kommt ein Simikolon. Also das ist eine der
merkwürdigsten Merkwürdigkeiten, die ich bis jetzt in Java kennengelernt habe.
Aber gut. Okay, und was für Felder hat diese Klasse?
Ciao, gar keiner. Es gibt dieses Lenks,
also in Wirklichkeit
gar nicht
Ja, das ist nur so ein bisschen syntaktischer Zucker,
sagen wir mal ganz gerne. Man kann also so ein Array,
es sieht so aus, als könnte man fragen,
hey, gib mir mal irgendwie diese Exeklavria-Belenks.
In echt passiert da irgendwas Magisches. Okay. Jetzt frage ich mal,
also entweder reicht euch das jetzt als Begründung,
dass man also fragen kann, gibt es dieses Feld und nein,
das gibt es gar nicht.
Oder ihr könnt sagen, nein, ich will noch tiefer einsteigen.
Also wer würde gerne noch tiefer in den Hasenbau rein und wissen,
was das mit diesem Lenken auf sich hat?
Ja, und wem reicht das jetzt langsam?
Oh, die meisten wollen es wissen.
Gut. Also ich habe hier unten jetzt nochmal
zwei weitere Methoden geschrieben
Die hörsten beide und längst auf, der einen Methode übergebe ich so
ein Wire-Objekt und der anderen Methode übergebe ich irgendeinen RAI.
Und ich greife jeweils auf diese Längseigenschaft zu.
Also dieses Punkt längst ist sozusagen wirklich,
ich greife auf dieses Lenkzug, was ich hier definiert habe.
Das ist also wirklich ein echter Zugriff auf ein Feld,
während das hier irgendwie diese, ja,
diese komische Magie von Java offenbar ist.
Dieses Feld gibt es ja eigentlich gar nicht, haben wir ja gerade festgestellt.
So, wo habe ich das Projekt eigentlich gespeichert,
das muss ich jetzt einmal wissen, um darauf zuzugreifen,
weil hier offenbar nicht,
habe ich das hier irgendwo gespeichert.
Ah ja
, da ist es
So. Genau. Und ich kann mir jetzt mal von dieser Mirror-Klasse angucken,
was macht eigentlich der Compiler aus diesen beiden Methoden?
Also das ist ja irgendwie so Java-Quelltext, ich schiebe den mal
irgendwie nach oben. So, das ist der Java-Quelltext.
Und wir schauen mal, was der Compiler daraus gemacht hat.
So. Und die spannenden Stellen, seht ihr hier unten.
Gut, keine Panik. Es ist ganz einfach,
es sind nur drei Zeilenquote, die ihr verstehen müsst.
Also diese Methode Langs of, die so ein Wire übergeben bekommt,
Da wird jetzt tatsächlich der virtuellen Maschinen gesagt,
ich möchte auf ein Feld zugreifen, warum das jetzt gerade fällt,
Nummer 17, ist es völlig egal.
Ja, okay. Und dann wird irgendwie zurückgegeben, was
in dem Feld drinsteht. Während diese Methode seht ihr,
statt Get Field steht jetzt hier so ein ganz besonderer Befehl
in der Java Virtual Machine, der heißt Array Langs.
Okay, das heißt also, wenn ihr auf einmal eure schreibt,
a.längs, dann wird daraus dieser spezielle magische, virtuelle Maschinenbefehl Array-Lings gemacht.
Ja, das ist sowas völlig anderes als auf dem Feld zuzugreifen.
Okay, ich glaube, magischer sollten wir heute nicht mehr werden, oder? Gut,
dann kommen wir vielleicht erstmal zu den ganz normalen Anwendungsfällen von Arrays,
aber ich hatte ja versprochen, oder Guido hat dafür versprochen,
dass ich es erkläre,
dann wollte ich dieses Versprechen auch einhalten
Okay, was wollen wir denn jetzt mal machen?
Also Error ist. Als erstes wollte ich mal,
wie nenne ich das mal, nenne ich das mal,
vielleicht mal Algos, irgendwelche tollen Algorithmen kommen da jetzt rein.
Guido hatte mich auch gebeten, mal diesen Algorithmus zu implementieren,
dass man zum Beispiel das kleinste Element eines Errors herausfindet.
Das können wir doch mal zusammen machen. Also nehmen wir
vielleicht ein Inter-Reel, wird das statt am einfachsten.
Also ich möchte einen Int zurückliefern, das kleinste Element,
ich nenne die Methode mal Minimum
Und was stecke ich rein? Die stecken internere rein und
das nennen wir einfach mal A, da einfach Katar.
Also es kommt ein Interare rein, da können beliebig viele
Insta drin stehen und ich will das kleinste Element zurückliefern.
Vielleicht sollen wir uns erstmal klarmachen,
wie man sowas per Hand machen würde.
Starte ich mal hier meinen Exo-Klon und kann man ja eigentlich irgendwie ranzoomen?
Gibt es hier sowas wie Maßstab, 200 Prozent?
Okay. Also stellt euch vor,
ihr habt ein RE,
da stehen irgendwelche Zahlen drin
So, keine Ahnung, vielleicht reicht das. Wie kann
man denn jetzt rausfinden, was das kleinste Element ist?
Das Problem für uns Menschen ist, wir sehen das sofort.
Also wir müssten uns jetzt eigentlich vorstellen,
dass die Liste so lang ist,
dass man das auf den ersten Blick gar nicht sehen kann.
Und dann ist ein ganz einfacher Algorithmus, das Minimum zu bestimmten
folgender. Ich mache mir mal so eine kleine Hilfsmariaple,
ich nenne die vielleicht mal, sagen wir mal, bisheriges Minimum.
Und da muss ich jetzt einen sinnvollen Startwert reintun.
Ich nehme mal den ersten Wert, diese 35. Ich tue jetzt also mal so,
als wäre das erste Element oder in Entschuldigung,
als wäre das kleinste Element ganz am Anfang des Erbes.
Könnte ja sein. Okay, dann Schaue ich mir mal
das nächste Element an. Und ich sehe jetzt,
oh, dieses Element ist ja kleiner als das bisherige Minimum.
Ich habe also sozusagen ein besseres Minimum gefunden. Dann kann ich sagen,
dann gehe ich mal davon aus, dass 17 das Minimum ist.
Dann schauen wir zur nächsten Zahl an. Die ist nicht
kleiner. Also ich habe kein neues Minimum gefunden.
Da kann ich die Zahl unten so lassen.
Das ist auch nicht kleiner. Das ist auch nicht kleiner.
Oh, ich habe ein neues Minimum gefunden. Diese Zahl
ist auch nicht kleiner. Und jetzt sind wir fertig.
Und wenn ich einmal durch das komplette RE durchgegangen bin und jedes Mal,
wenn ich eine kleinere Zahl gefunden habe, die ihr unten gespeichert habt,
dann haben wir am Ende die kleinste Zahl.
Das glaubt mir hoffentlich jeder. Vielleicht kann man das
irgendwie noch formal beweisen, aber ich glaube,
das ist nicht notwendig
Also wir gehen davon aus, es steht am Anfang und
dann schauen wir, ob wir ein besseres Minimum finden.
Das müssen wir jetzt nur noch in Java programmieren.
Also diese Box hier unten, bisheriges Minimum,
die kann ich jetzt ja einfach mal deklarieren.
Also bisheriges Minimum ist gleich. Wie sage ich denn jetzt,
ich möchte den Wert kopieren, der ganz am Anfang des RS steht.
Wie sage ich das in Java? Ich muss jetzt da
irgendwie auf den Anfang des Errichs zugreifen.
So, genau, gib mir doch bitte das Element,
was bei A an der Stelle null steht.
Gut. Und jetzt will ich über alle anderen Elemente
rüber iterieren. Also fangen wir doch mal an.
Vorschlafen kennt ihr ja. Wir fangen an Stelle
eins an
Ja, hier weiß ich noch nicht genau, was ich
da reinschreiben muss und anschließend muss ich eh immer um einen erhöhen.
Und jetzt will ich die Frage stellen,
steht an der Stelle eh etwas kleineres als in dieser Variable?
Wie formuliere ich das in Genre, diese Abfrage?
Irgendwie mal Hände hoch, wenn das jemand weiß,
du weißt es, sonst keiner?
Wirklich nicht. Ja. Sowas wie FD ist ein
kleiner Ansatz. Das schreibe ich erstmal hin, dass alle
darüber nachdenken können
Richtig, ich will ja nicht die Positionen abfragen,
die Position wären hier ja 0, 1, 2,
3, 4, 5, 6,
die interessieren mich nicht, die Positionen, sondern ich will wissen,
was steht denn an der entsprechenden Stelle in dem RAL?
Okay, und was mache ich,
wenn ich was Kleineres gefunden habe, vielleicht nochmal irgendjemand anders,
wie kopiere ich mir jetzt den Inhalt in meine andere Variable rein?
Ja. Genau. Hat jemand aber gesagt? Oder habe
ich mir das eingebildet, ne, keine Einwände?
Fehlt noch irgendwas? Das hier oben ist ja sicherlich kein
gültiges Java, ne? Wie lange muss ich denn weiterschleifen
Was muss für I gelten, damit ich nochmal, ja?
Genau. Und wie sage ich in Java, die Länge des RES?
Genau. Fehlt jetzt noch was? Ja. Wir müssen
bei null anfangen. Das ist eine interessante Frage. Also,
wir haben ja ganz am Anfang, haben wir ja gesagt,
ich kopiere mir die 35 hier rein.
Dann war der Stand sozusagen so. So,
und jetzt ist die Frage,
muss ich jetzt hier anfangen nach besseren Werten zu suchen oder
muss ich hier anfangen nach besseren Werten zu suchen?
Ist egal eigentlich, ne
Was sagst du? Es ist oft bei One, sagst du? Okay,
wir können ja mal die Position hier dahinter schreiben,
0, 1, 2, 3, 4, 5,
5, 6. Das heißt, die Länge ist sieben.
Jetzt ist die Frage, muss hier jetzt noch stehen,
minus eins? Also muss ich, muss die Position kleiner
sein als sechs oder muss sie kleiner sein als sieben?
Wer ist der Meinung, dass es diese minus eins dahin muss?
Fast niemand, wer ist der Meinung, dass es nicht
hin muss?
Genau. Sehr schön
Denn der letzte gültige Index ist ja kleiner als die Länge.
Es ist also nicht so, dass die Länge sechs ist.
Die Länge ist tatsächlich sieben. In einem Ere der Länge sieben
gehen die Elemente von null bis sechs oder die Position.
So. So, sieht jetzt noch jemand einen Fehler?
Ja. Genau, wir müssen irgendwas zurückgeben. Ich habe
ja hier an dieser Stelle versprochen, dass wir etwas zurückgeben.
Also, Return, series Minimum. Okay, dann probieren
wir das doch mal, machen wir das mal zu.
Wo ist mein Algors? Auch wir können das auch mal
Stating machen. Ich habe keine Lust mehr davon,
ein Exemplar zu erzeugen
Vielleicht nochmal als Kontrast, damit ihr nochmal versteht,
welchen Unterschied es macht, ob ich Static mache oder nicht.
Also das ist jetzt eine ganz normale Methode.
Wie rufe ich die Methode auf? Ich erzeuge mir ein
Exemplar, so wie wir das seit Woche 3 kennen.
Und dann kann ich an diesem roten Exemplario die Methode aufrufen.
So, wenn ich das jetzt Static mache,
dann gehört diese Methode nicht mehr zu den Exemplaren,
sondern zu der Klasse selber.
Jetzt kann ich also auf der Klasse selber die Medium Methode aufrufen.
Dann brauche ich kein Exemplar mehr erzeugen.
Das bedeutet Static in Blue J. Vokabular sozusagen.
Gut. Ja, wie benutzen wir das denn jetzt mal?
Wir erzeugen uns mal ein RE.
Klar, Entschuldigung. Nehmen wir mal, keine Ahnung.
So, was tun wir da jetzt mal rein?
Also wir tun mal anstatt null Tumor rein, 42.
Ich stelle eins drüber rein. Sieben, da haben
schon mal eine 123 rein und dann tun wir eine.
Drei Reihen. So, und jetzt möchte ich diese Methode aufrufen.
Also ich kann jetzt direkt an der Klasse sagen,
ruf doch mal die Minimum-Methode auf und übergebe A.
Was wird da denn jetzt rauskommen? Hier seht ihr ja
den Code
Ich war, ich übergebe süßes A,
was ich da unten mir da, okay.
Ich kann ja mal eine Abstimmung machen. Wer glaubt,
dass 42 rauskommt? Drei Leute. Wer glaubt,
dass sieben rauskommt? Keiner. Wer glaubt, 123?
Und wer glaubt drei? Ja, so ein Dutzend.
Wer glaubt irgendwas anderes? Ah, die meisten.
Sehr schön. Richtig. Was kommt denn daraus?
Einfach mal in den Raum hofen? Null. Da ist
die Null. Warum? Wenn wir uns dieses Ari
noch mal kurz angucken,
einfach als Wiederholung
Dann hatten wir gesagt, es soll ein R mit zehn Zahlen sein.
Und hier ist über die zehn Zahlen. Also wenn ich
das R erzeuge, sind da zehn Nullen drin.
Und ich kann diese Nullen überschreiben mit anderen Elementen.
Aber es ist nicht so, dass diese Einträge irgendwie leer wären oder so.
Das glauben viele Programmieranfänger. Also wenn ich an R
der größte Zehn erzeuge, sind da zehn Instaen.
Das ist nicht irgendwie Platz für zehn Ins und ich fülle das auf oder so.
Sondern es sind wirklich zehn Ins und wenn ich will,
kann ich da über die Zahlen ändern.
Okay. Gut. Dann habe ich das auch gemacht.
Dann würde ich eigentlich ganz gerne noch ein bisschen was
mit Primzahlen machen
Ich liebe Japrin-Zahlen. Gott, wie schreibt man den Herrn?
Ich glaube so. So. Das ist jetzt alles vielleicht
ein bisschen unübersichtlich, dass alles im selben Projekt ist,
aber so schlimm ist es nicht.
Ich glaube, wir hatten schon mal irgendwelche Zusatzaufgaben in SR1,
wo es um Primzahlen ging. Aber ich würde nochmal eine
etwas spannendere Aufgabe damit machen. Genau. Also,
ich brauche jetzt hier ein relativ großes Raster von Zahlen.
Ich überlege gerade, wie ich das möglichst geschickt hinkriege,
kann ich das nicht irgendwie so automatisch machen,
dass er mir das hier so hochzählt quasi?
Ja. Und dann will ich hier irgendwie immer zehn mehr
haben, als hier steht.
Geht das irgendwie auch einigermaßen schnell
Ja, okay. Und dann kopiere ich mir das mal hier so runter.
Okay. Also das soll eigentlich ein eindimensionales irre sein,
aber ich wollte jetzt nicht 100 Spalten haben und eine Zeile.
Also stellt euch bitte vor,
das ist ein eindimensionales irre ist und ich habe das jetzt
nur der Übersichtlichkeit, teilweise so ein bisschen zweidimensional dargestellt.
Okay. Also es gibt einen Algorithmus, das heißt,
der siebte ist Ära Tostin. Wer hat das schon mal
gehört? Ja, so ein, zwei Dutzend Leute.
Das ist eigentlich ein tolles Anwendungsbeispiel für RAS.
Der funktioniert einfach so, man überlegt sich im Voraus,
bis wo will ich meine Primzahlen bestimmen?
Ich will also hier in diesem Fall alle Primzahlen bestimmt,
die kleiner sind als
So. Und dann kann man eigentlich schon mal gedanklich die 0
und die 1 irgendwie, wie kann ich die denn mal auswenden?
Also löschen will ich es nicht, sonst gehen mir ja
die Formeln, gehen mir die Formeln kaputt.
Irgendwie so grau oder so. Ja, jetzt sieht man
sie nur noch so hype, ne?
Okay, wir fangen mal bei der 2 an.
Die 2 ist schwarz. Das bedeutet, dass die 2
eine Primzahl ist. Das müssten wir jetzt einfach mal glauben.
Also die 2 ist eine Primzahl. Jetzt müssen wir alle
Vielfachen von 2 ausblenden. Also zum Beispiel die 4 müssen wir ausblenden,
die 6, die 8, die, die,
ne,
die nicht
Zehn, die 12, die 14, die 16,
die 18. Also ich mache das jetzt nicht für alle Zahlen.
Ich deute das jetzt nur mal so für die ersten zwei an.
Die habe ich jetzt alle ausgeblendet. Vier ist keine Prinzial,
weil das ist ja zweimal zwei. Sechs ist keine Prinzial
, weil das ist ja dreimal zwei. Ach,
das ist keine Prinzial, weil das ist ja viermal zwei.
Klar, ne? Okay, das habe ich jetzt hier für alle gemacht.
Und jetzt geht es weiter im Text. Oh,
die drei ist schwarz, die musste drei auf der Prinz,
weil da muss ich jetzt alle Vielfachen von drei ausblenden.
Also ich muss die sechs ausblenden, die ist zwar schon ausgeblendet,
aber ich mache es ja vorsichtshaltshalber nochmal.
Die neuen, die zwölf, die 15,
die 18, 21, ja siebenmal,
achtmal,
neunmal und so weiter
So die Vier ist jetzt keine Primsaal, weil wir haben die ja ausgeblendet,
als wir die Vielfachen von zwei ausgeblendet haben.
Gut, die Fünf ist jetzt wiederum eine Bremenzahl,
also muss ich die Zehen ausblenden, die 15,
die 20, die 25 und so weiter.
So, die sechs, hatten wir schon ausgeblendet,
ist Vielfaches von zwei, ist Vielfaches von drei.
AT7 ist eine Bremenzahl, da muss ich die 14 ausblenden,
die 21, die 28, die 35 und so weiter.
Acht hatten wir schon ausgelendet bei der 2,
9 hatten wir bei der 3, ausgelendet,
10 bei der 2, oh,
11 Steine Premenzahl zu sein.
Und da geht das Spiel immer so weiter.
Ist das so halbwegs verständlich,
einmal ein Tuch
Ja, okay, gut. Das wollen wir dann jetzt mal zusammen programmieren.
Okay. Wir fangen vielleicht auch erstmal ganz einfach an mit einer statischen Methode,
weil so richtig schön Objekte orientiert, das jetzt aufzuzahlen,
wird mir, glaube ich, in 15 Minuten nicht gelingen.
Das können wir vielleicht am Anfang der nächsten Vorlesung nachholen.
Also, wir machen eine Methode. Was soll sie denn zurückliefern?
Darüber haben wir uns noch gar keine Gedanken gemacht. Also,
eigentlich ist es selbstverständlich, sie soll mir zurückliefern,
ein RAE, wo drin steht, zwei, drei,
fünf, sieben, elf,
also alle schwarzen Zahlen sozusagen,
will ich einfach in so
ein RAE reinstecken
Okay, also sie soll ein Eric zurückliefern,
das kann man eben auch auf der Rückgabetyp kann ein Eric sein.
Und dann nennen wir das doch mal Kell, Q,
Late, Primes, Below, in,
wie nennen wir jetzt mal, die Grenze, Bound,
heißt Bound-Grenze oder Boundary, ich nenne es mal Bound.
Also wenn zum Beispiel jemand 100 übergibt, dann würde ich
alle Primzahlen berechnen, die kleiner sind als 100. Gut.
So, jetzt muss ich mir ein RA anlegen,
wo ich zwischen grau und schwarz unterscheiden kann.
Jetzt gibt es in Java keinen Datentyp,
der genau aus den beiden Werten grau und schwarz besteht.
Kennt jemand einen anderen Datentyp, der aus zwei verschiedenen Werten
besteht in Java
Genau. Wir können uns einen Bulien-RA anlegen. Also,
das nennen wir vielleicht mal Ist's Prime,
dann liest sich der Quelltext, glaube ich, ganz nett.
Und dann erzeugen wir uns, dass RA mal ein Bulien-RA der Größe boundt.
Also, wie gesagt, wenn Bounty Wert 100 hat,
kriege ich jetzt eine RA der Größe 100,
wo hundertmal der Wert Fouls drinsteht.
Und das geht halt von 0 bis 99. Gut.
Jetzt sind die alle Falls. Falls klingt ja so wie nicht prim,
aber ich muss ja am Anfang erstmal ausgehen, dass alle prim sind.
Also, ich muss jetzt eigentlich erstmal alle zahlen,
oder alle Einträge auf True setzen.
Ich mache das jetzt einfach mal ganz schnell mit einer Vorschleife
Wir könnten es auch umgekehrt machen, weil dann liest es sich so blöd.
Bei der Vorbereitung zu Hause habe ich es gelesen,
es sind überall so Ausrufezeichen. Das ist pädagogisch einfach nicht
so gut. Okay. Also ich schleife jetzt hier von
0 bis 99 quasi in unserem Beispiel und sage einfach,
ist Prime an der Stelle Isolt-Shoot sein.
Gut, dann sind es jetzt quasi alle Zahlen schwarz.
Ja, und jetzt hatte ich ja gesagt,
wir müssen bei der 2 anfangen. Das ist so
ein bisschen ungewöhnlich, dass man bei der 2 anfängt.
Das hat einfach mit der Eigenschaft von Primezahlen zu tun.
Also wenn ich jetzt zum Beispiel bei 1 anfangen würde,
dann würde ich, wenn ich dann alle Vielfachen von 1 grau mache,
dann würde ich ja alles grau machen.
Das wäre sicherlich nicht
so sinnvoll
Und wenn ich bei null anfangen würde,
dann würde ich alle Vielfachen von null ausblenden,
also die null, die Null, die Null, die Null.
Und ich würde niemals fertig werden. Also das hier,
wenn eine Endlosschleife und hier würden alle Zahlen grau gemacht werden,
das wäre sicherlich nicht so sinnvoll.
Und wir wissen ja auch, dass die erste Friedenzahl die Zahl zwei ist.
Also fangen wir an mit der Zahl zwei.
Ja, gehen wir wieder alle Zahlen durch. So,
und was hatte ich jetzt gesagt? Ich hatte ja gesagt,
wir müssen gucken, ob die Zahl schwarz oder grau ist.
Wenn sie schwarz ist, haben wir eine Prinzzahl gefunden,
dann müssen wir dich vielfachen ausgrauen.
Und wenn sie grau ist, müssen wir eigentlich
nichts machen
Gut. Dann schauen wir doch mal,
ob sie schwarz ist, ob es eine Premza ist.
Also, wenn ist Prime an der Stelle I,
den wer True hat. Könnte man ja hinschreiben. Ich
schaue, was steht in einem Array drin und vergleiche,
ob es der wert True ist.
Sieht jemand, dass man das auch kürzer schreiben kann,
diese Anfrage? Ja. Ist gleich 5, weglassen,
weil das ist ja ein Array Computer.
Genau. Also die Frage, ob es True oder Fords
ist, macht das If ja sowieso schon.
Das If wird sich ja diesen Ausdruck anschauen und sagen,
wenn dieser Ausdruck wahr ist, dann muss ich diesen Blog ausführen.
Und deswegen habe ich noch die Variable extra East Prime genannt,
weil If is Prime E,
klingt einfach toll
So. Was hat denn gesagt, was ich machen muss,
wenn es eine Primzahl ist? Dann muss ich
alle Vielfachen ausblenden. Also zweimal i, dreimal i,
viermal i, fünfmal i, sechsmal i und so weiter.
Die müssen alle ausgeblendet werden. Dann versuche ich das immer
. Ich muss jetzt also eine weitere Schleife schreiben.
Wenn wir mal vielleicht K als Schleifenzähler.
Was wäre jetzt ein sinnvoller Startwert für K?
Ja. I. Dann würde ich ja i selber auch ausblenden.
Das wäre nicht so gut, oder?
I plus 1 ist ja kein Vielfaches von ihr.
Ich will ja nur über die Vielfachen von ihr rübergehen
Da meldet sich jemand. Zweimal ihn, genau. Ich fange bald zweimal i an.
Dann darf ich sicherlich wieder nicht über meine Ehre-Grenzen rüberkommen.
Und wie soll ich das K jetzt verändern?
Also ich will ja, nachdem ich zweimal abgearbeitet habe,
muss ich ja als nächstes zu dreimal i gehen,
dann zu viermal i, dann zu fünfmal i.
Was ist denn der Abstand zwischen zweimal i und dreimal i?
I, K plus gleich i, ne?
Sehr schön. Und wie sage ich jetzt,
ich möchte in dem RA namens Is Prime an der Stelle K,
möchte ich das jetzt grau machen,
in Anführungsstrichen.
Wie schreibt man das in Genre
Ja. So, ne? Woods mit kleinem E. Genau.
Das wird es genau machen. Das wird vier ausgerauen,
sechs, acht, zehn, zwölf und so weiter.
Gut. Wollen wir vielleicht, um erstmal bis hierhin uns
zu versichern, dass da nicht völliger Unsinn passiert ist.
Einfach mal, dass er auf die Konsole schreiben.
Einfach mal gucken, was drinsteht.
Ist Prime. So. Oh, das ist ein Bulien-Erry.
Warum habe ich da Intin geschrieben und keiner hat es gemerkt
Return-Statement fehlt, da kann ich noch nichts zurückgeben,
gebe ich einfach mal Nal zurück.
Hups. Okay. Ich will einfach mal schauen,
wenn wir das ausführen, was dann passiert.
Ach nee, Quatsch, ich kann es auch direkt hören.
Ich hatte es, ich habe es nicht steady gemacht.
Warum habe ich das nicht steady gemacht?
Ich will es direkt auf der Klasse ausführen.
Ich habe immer keine Lust mehr Exemplare zu erzeugen.
So, nehmen wir mal vielleicht 20.
Das ist nicht so eine lange Liste wird
Okay. Kommt das jemandem bekannt vor? Irgendwie so eckige
Klammer auf und dann so ein merkwürdiges Zeug irgendwie, das
haben wir vorhin schon mal gesehen. Das heißt also,
wenn ich an R ja auf die Konsole schreibe,
dann sieht man leider nicht, was in dem RA drinsteht,
sondern Java sagt mir, du, das ist ein RA von Bulliens.
Bullien wird mit Z abgekürzt, frage mich bitte nicht, warum.
Und irgendwie an der Speicheradresse sowieso findest du dieses RA.
Das ist ja toll. Jetzt habe ich aber keine Lust,
da irgendwie so rüber zu schleifen.
Ich zeige euch mal einen kleinen Trick. Es gibt so
eine kleine Hilfsklasse, die heißt Java Yoto R ist.
Da sind so ein paar nette Methoden und mit denen,
wo ich was Sinnvolles mit RAS machen kann.
Ich kann zum Beispiel sagen, rs.to string is prime.
Er nimmt also dieses R, geht über die Elemente,
macht auch irgendwie so einen tollen String mit Commander getrennt und so.
Das will ich nicht alles selber machen. So, neuer
Test. So, jetzt schauen wir doch mal. Also,
die beiden Elemente ignorieren wir, die interessieren uns gar nicht, 001. Also,
1. Meinung 2 ist eine Primzahl, 3,
4 nicht, 5 ist eine Primzahl, 6 nicht,
7 ist eine Primzahl, 8 nicht, 9 nicht,
10 nicht, 11 ist wieder eine Primzahl,
die sieht doch ganz gut aus, oder?
13 ist eine Primzahl, haben wir hinten hoffentlich noch 17
und 19. Also so intern dieses Sieb mit den Farben,
das scheint schon mal zu stimmen
Das ist doch schon mal ganz erfreulich. Hat jemand bis
hierhin erst mal eine Frage? Ja. Diese größere Scheiße
gibt es. Ja, das reicht. Das wollte ich
noch als Bonus sagen, wenn nachher die Zeit erreicht.
Sehr, sehr schön. Ja, sonst noch eine Frage?
Ich sehe keine Hand. Okay. Ja, dann ist jetzt
unsere nächste Aufgabe. Wir haben jetzt also quasi in diesem Eri,
diese ganzen True, True, Fouls, True,
Fouls, True, Fouls, Fouls.
Und ich will jetzt, aber nicht den Benutzer dieses Bulien-Eri
zurückgeben, sondern ich will ihn tatsächlich diese Zahlen zurückgeben.
Jetzt ist es ja so, wenn ich so ein Eri erzeuge,
so ein Intere, muss ich ja sagen,
wie groß es ist
Wie groß ist dieses, wie groß muss dieses Erre
denn sein, was ich dem Benutzer zurückgebe?
Hängt ja davon ab, wie viele Primzahlen ich gefunden habe.
Also wäre es vielleicht ganz gut, wenn wir erst mal zählen,
wie viele Primzahlen wir tatsächlich gefunden haben.
Ich nehme das jetzt mal wieder weg, das brauchen wir nicht mehr.
Ich möchte jetzt also einmal durch mein ganzes RAI durchgenutzt zählen,
wie oft steht da der Wert True drin?
Ich mache jetzt also hier wieder ab Position 2. Dann gucke ich
einfach, wenn I eine Primzahl ist. Ach so,
jetzt muss ich irgendeinen Zähler erhöhen, den ich noch gar nicht habe,
dann muss ich den auch mal einführen.
Nehmen wir den mal,
Count vielleicht
Also am Anfang habe ich noch keine gefunden. Und jedes Mal,
wenn ich eine finde, dann erhöhe ich diesen Zählern.
Ich weiß nicht, wie sowas in der Richtung
schon mal formiert haben, zählen irgendwie.
Ja, ist, glaube ich, ganz einfach.
Aber nochmal haben wir nichts gefunden. Und jedes Mal,
wenn wir eine finden, erhöhe ich diesen Zähler.
Das sollte hoffentlich nicht zu schwierig sein. So,
jetzt weiß ich, wie viele Primzahlen es sind.
Und jetzt würde ich mir gerne einen Eric dieser Länge erzeugen.
Das ist ganz einfach. Ich sage einfach,
ich brauche einen Interre, das nennen wir mal vielleicht Primes.
Und ich erzeuge jetzt ein neues Interrede, ja,
welcher Länge. Welche Länge muss ich jetzt hinschreiben?
10 oder 100 oder 1000
Count,
Gut. Und das kann ich dann auch später zurückgeben.
Natürlich steht da momentan ein Quatsch drin. Da stehen jetzt
ganz viele Nullen drin. Was muss ich denn jetzt als nächstes machen?
Also ich habe dieses Sieb mit den ganzen Truths und Fouls.
Und ich habe jetzt schon das Ehre, wo die Prinz Hammer rein soll.
Wie kriege ich die denn jetzt da rein, die Prinzessin?
Kann man die Ideen? Ja, das ist quasi so
der Schleifenrum, den du gerade erklärt hast, genau.
Also ich brauche schon wieder die Schleife von hier quasi.
Ich kopiere mir jetzt einmal, ich habe keine Lust,
das normal zu schreiben.
Eigentlich kann ich mir fast alles kopieren, oder?
Ich kopiere mir immer
fast alles
Bis auf das. Also, ich gehe jetzt wieder komplett
durch. Und wenn ich eine Primzahl finde,
dann will ich den Index I in dieses Primes Erre reinschreiben.
Primes, tja, aber an welcher Stelle denn?
Das müssen wir uns gar nicht mal überlegen. Soll I
sein. Also, wenn ich anstelle 2 eine Primzahl finde,
schreibe ich die 2 in die Liste rein.
Entschuldigung, in das RE. Wenn ich anstelle 3
eine Primzahl finde, schreibe ich 3 rein.
Wenn ich anstelle 7 eine für eine 11, 13 und so weiter.
Und 5 sicherlich auch. Aber an welcher Stelle muss ich
das denn jetzt schreiben? Ich kann jetzt ja nicht einfach sagen,
Liebeserre füge das doch mal hinzu, so wie bei einer Errelist zum Beispiel.
Da kann ich ja sagen, fügt das bitte nacheinander hinzu.
Das geht hier nicht. Ich muss ja sagen,
an welcher Stelle es geschrieben werden soll.
Was machen wir denn jetzt
Nein, warum Fehler machen? Und dann die Ventile immer
als Hummeln, wenn man einführt. Genau. Nenne ich
das jetzt einfach mal J. So. Und dann schreibe ich es
an die Stelle J und dann muss J erhöht werden.
So. Macht das Sinn? Ich glaube ja.
Fragen? Über welche Zeile redest du gerade?
Hier? Wir beide mit einem. Hier? Theoretisch kann
man einfach wieder mitsetzen
Ich habe dann, das stimmt, aber ich habe deine Frage nicht verstanden.
Kannst du die fahren? Ah, ihr wollt dieselbe Variante nochmal benutzen?
Vielleicht, wenn du das wegfährst und das beweisen kannst.
Gott, Ambitionssteuer ist leicht. Ja, ich meine,
wenn euch das glücklich macht, kann ich auch gerne dieselbe
Variable nochmal nehmen, aber also so so und so.
Es ist das, was du meintest.
Es müsste das gleich machen. Wahrscheinlich ja,
weil wir die Variante Account ja anschließend nicht mehr benutzen.
Ich weiß noch nicht, ob das so schön ist,
weil Account,
naja,
Du würdest es gerne hier direkt in diese selbe Schleife reinmachen.
Das geht nicht, weil ich ja an dieser Stelle
sagen muss, wie groß das Ere sein muss.
Also wenn ich ein Ere erzeuge in Java,
kann ich nicht sagen, liebes Java, ich weiß noch nicht genau,
wie viele Elemente da später mal drin landen werden,
macht das bitte dann bei Bedarf größer.
Das geht nicht. Okay. Oh, wir haben
nur noch vier Minuten verdammt. Gut, dann schauen wir
doch mal, ob das jetzt funktioniert.
Dann sage ich doch, wenn ich hier unten,
warum habe ich die Klasse so kompliziert genannt?
Jetzt muss ich das hier jedes Mal abtippen. Karl,
Julette, Primes, Pelow 100. Okay, jetzt haben wir so eine kleine Referenz.
Den nennen wir mal A. Und jetzt wird hier wieder dieser
Quatsch auf der Konsole erscheinen, wenn ich einfach nur A,
ach ne, er sagt gar nichts, okay.
Jetzt muss ich wieder sagen, Java, Youthil,
RAs to String, ah, ich will einfach mal gucken,
was dabei rauskommt.
Habe ich auch was anderes gemacht. Sind wir Kohle?
Aber ich würde auch einfach nur diesen String sehen
Muss ich jetzt hier auch noch zu so einem Output?
Das ist ja furchtbar. Ich hatte gehofft, dass es einfach so geht.
Oder kann ich einfach sagen, string ass ist gleich.
Und dann erst, ah ja, schauen wir mal.
Sieht das aus wie Primzahlen? Ja, ne?
Bis 97. Ja, wunderbar. Das ist auch toll.
Jetzt kopiere ich mir mal diesen String, ne?
Und jetzt war ja schon dieser Vorschlag mit dieser Optimierung gekommen.
Und immer bevor ich Quelltext optimiere,
muss ich irgendwie sicher sein, dass ich einen Test habe,
dass ich irgendwie nichts kaputt mache durch diese Optimierung.
Ich mache mir jetzt immer einen Test,
einen Unit-Test kennen wir ja schon aus dem letzten,
oh, lass euch auch einen Namen geben,
sagen wir mal, Ära, testen ist.
So, da machen wir hier mal Private, Ära,
Thos, Tenes und jetzt nehme ich jetzt mal die Zwischenablage.
Ah ne, es ist ja Static, ich brauche ja
gar kein Exemplar. Ha, toll. Das kann ich
mir alles sparen. Das kann ich mir auch alles sparen.
Ich brauche eigentlich nur mal eine ganz einfache Testmethode.
So, Test bis 100 oder so, keine Ahnung.
Das sage ich jetzt
also folgendes
Also ich mache mir erst mal so ein R-Re mit den Werten, die ich erwarte.
Expected ist gleich. Und jetzt kommt dieses Tolle,
ach, ich habe immer eine Zwischenablage kaputt gemacht.
Moment, ich habe es hoffentlich hier unten noch, genau.
Jetzt kann man ja in Java so toll Erics initialisieren.
Ich muss jetzt also nicht 100 Zuweisungen schreiben oder wie
wir sind das, 20 Prints sein oder so.
Sondern ich schreibe jetzt hier einfach direkt hin. Ja,
leider sind die Klammern falsch, die muss ich jetzt
von Hand korrigieren, das muss geschweift Klammern sein.
So. Ja. Das ist also das, was ich erwarte.
Und dann hole ich mir über das R-Revers tatsächlich dabei rauskommt.
T-nächst.caltunate primes be law 100. Und jetzt erwarte ich,
dass das gleich ist. Expected und actual. Ja,
das ist auch ein sinnvoller Unit-Test, oder?
Ich habe hier dieses R mit den Zahlen,
von denen ich weiß, dass sie richtig sind.
Dann gucke ich, was kommt denn tatsächlich raus,
wenn ich die ersten 100 Primzahlen berechne.
Und dann sollte das ja sicherlich gleich sein. Und bevor
wir jetzt diese Optimierung machen, lasse ich den Test einmal durchlaufen.
Ich meine, ich habe die Testdaten ja aus dieser Methode,
also das muss ja eigentlich gleich sein.
Das probieren wir jetzt einmal aus, lasst mal einmal laufen.
Das ist ja komisch
Tja, jetzt seht ihr schon wieder diesen Unsinn, der hier steht.
Also, Share Unit sagt, nein, nein,
nein, nein. Das eine RA liegt ja hier im
Speicher und das andere RA liegt ja hier im Speicher.
Das ist nicht gleich. Also, J. Unit nimmt quasi
die Speicheradresse oder die Identität der RAS. Das will ich
nicht. Und ja, zum Glück gibt es auch eine Testmethode,
die heißt Asserd Array Equals oder Arrays Equals.
Ich bin mir nicht ganz sicher, wie sie heißt.
Ja, genau. Wo sich wirklich die Inhalte der RAS
anguckt und die miteinander vergleicht. Machen wir das doch mal,
ob das jetzt funktioniert? Genau. So, und warum
hatten wir das jetzt gemacht? War ja der Vorschlag kam,
Dass man an dieser Stelle,
wo man die Premenzahlen identifiziert und wo man das ausgrauen und so macht,
dass man da gar nicht bis zum Ende des RAS gehen muss,
sondern dass es quasi reicht, dass man sagt,
ich gehe bis zur Wurzel, jetzt muss ich immer so ein bisschen das beschleunigen.
Wenn ihr die Wurzel berechnen wollt, hatten wir,
glaube ich, schon mal gesehen,
ruft man einfach auf der Klasse Marv die statische Methode des Gerüt auf.
Das ist einfach ein statischer Methodenaufwurf, kennt ihr jetzt ja auch.
Dann mache ich da auch mal einen Int.
So. Und warum reicht es denn bis zur Wurzel zu gehen?
Wo war der Hertha, der das vorgeschlagen hatte?
Ergibt. Okay, also die Frage ist jetzt quasi,
wenn ich hier bis 100 gehe,
dann brauche ich zum Beispiel nicht die Vielfachen von elf auszublenden.
Warum muss ich die Vielfachen von elf nicht ausblenden?
Zum Beispiel die 22, die wurde ja schon ausgeblendet,
als ich die Vielfachen von zwei ausgeblendet habe. Die wurde schon ausgeblendet,
als ich die Vielfachen von drei ausgeblendet habe,
die bei vier, die bei fünf, die bei sechs,
die bei sieben, die bei acht und die bei neun.
Die einzigen, die ich jetzt noch nicht theoretisch ausgeblendet habe,
sind Vielfache von elf, wo der andere Faktor eben auch mindest.
Zum Beispiel elf mal elf habe ich nicht ausgeblendet,
aber das ist ja schon viel zu groß.
Ich wollte ja nur bis 100 gehen
Das ist eine tolle Übungsaufgabe, dass sich mal zu Hause klarzumachen,
mathematisch, weil man es reicht, da bis zur Wurzel zu gehen.
Okay. Ja, jetzt testen wir, ob das mit dieser Optimierung immer noch geht.
Wir haben ja jetzt hier zum Glück unseren Test geschrieben.
Es funktioniert immer noch. Das ist doch schön. Ja,
jetzt, das ist hier ganz schöner Spaghetti-Code, irgendwie vier Vorschleifen,
so direkt untereinander, mehrere RS. Ich bin dafür,
dass wir einfach mal nächste Woche vielleicht damit anfangen,
vielleicht kriege ich mal fünf Minuten mehr,
dass wir das mal so ein bisschen entzerren und so ein
bisschen lesbarer machen.
Vielen Dank bis nächste Woche