Schön, schön. Herzlich willkommen zur neunten Vorlesung von
SE1. Wir haben jetzt nur noch zwei Vorlesungen vor Weihnachten.
Dann habt ihr erst mal Ruhe. Und wie üblich habe
ich ein paar Worte vorneweg? Das erste ist,
dass viele von euch inzwischen den Online-Selbsttest durchgeführt haben für Level
1. Wenn man sich das hier anguckt,
dann kommen sie, dann sieht man,
dass da bisher 438 mal der Test durchgeführt wurde
Das sind schon so fast alle von euch.
Das ist gut. Aber man sieht auch, dass nicht
ganz so viele den Test für Level 2 durchgeführt haben.
Das ist, hier sind das nur 107 Durchführungen bei dem Selbsttest von Level 2.
Das ist natürlich wieder ein bisschen interessant für uns.
Also fragen wir gleich mal wieder unser Orakel von Storesi.
Warum das so ist? Hier ist die Frage,
ich habe den Online-Test zu Level 2. Ah,
bisher nicht durchgeführt, weil ich noch keine Zeit dafür hatte
Durchaus sein. Oder bisher nicht durchgeführt,
weil ich inhaltlich noch nicht so weit bin,
weil ich möglicherweise in den Übungen noch nicht mit Blatt 8 fertig seid.
Oder C, ihr habt das nicht vor, den durchzuführen,
weil euch der Test für Level 1 nichts gebracht hat.
Oder ihr habt ihn durchgeführt und nicht bestanden. Oder ihr habt
ihn durchgeführt und bestanden. Gibt doch mal kurz eure Stimme ab,
damit wir da mal so ein bisschen so einen Eindruck bekommen.
Auch die Zuschauer an den Bildschirmen da draußen,
jetzt live am Livestream hängen, können auch teilnehmen.
Über ihr Smartphone. Ja. Das ist noch nicht
so wahnsinnig viel, was Jan Stimmen reinkommt.
Okay, wir beenden das mal. Einfach, dass wir
mal so einen Eindruck bekommen. Okay. Also die Mehrzahl
sagt, sie hatte noch keine Zeit, das durchzuführen.
Die, die ihn schon durchgeführt haben,
da haben immerhin
die meisten
ihn bestanden
Also das ist hier deutlich weniger. Wir können ja mal
eben gucken, was hier mit den absoluten Stimmen ist.
Also hier sind auch welche durchgefallen. Was ist denn hier
? Einer sagt es ihm, dass es nichts bringt.
Okay. Ja, das ist legitim. Völlig legitim. Gut,
also das ist ja schon mal eine ganz interessante Zahl.
Gut, gut, gut. Dann wird es ab morgen
schon wieder einen neuen Test geben,
weil der Level 3 ist ja schon wieder zu Ende.
Heute beginnt ein Quatsch. Der Level 3 ist jetzt
noch hier die zweite Woche. Also diese Vorlesung gehört noch
zu Level
Und in der nächsten Woche beginnt dann Level 4. Das heißt aber,
dass diejenigen,
die heute hier sind und morgen in der Übung sitzen,
schon morgen ihren Level 3-Test durchführen können,
wenn sie mit Level 3 schon durch sind.
Okay, soviel zu den Tests. Dann endet heute der Twittle
Graphics Creativity Contest. Wir haben schon einige Einreichungen bekommen.
Heute Abend um Mitternacht oder so könnt bis heute Abend,
danach könnt ihr noch einreichen.
Also nur Mut. Das wird bestimmt ganz lustig.
Nächste Woche gibt es dann die Preisverleihung hier in der Vorlesung
Okay, dann habe ich noch was, eine Kleinigkeit,
eine Metapher, die ihr möglicherweise hilfreich findet.
Ich weiß nicht, ob ihr es schon mitbekommen habt,
aber ihr könnt Programme schreiben in Java, die der Compiler akzeptiert,
die aber nicht das machen, was ihr erwartet.
Also Programme können unsinnig sein, auch wenn sie übersetzbar sind.
Das ist nicht weiter überraschend, weil Quelltexte,
also das, was ihr schreibt, in Java,
das kann man auffassen wie Baupläne für Maschinen.
Das heißt, aus so einem Bauplan kann eine Maschine entstehen,
also aus einem Quelltext kann ein lauffähiges System entstehen
Der Bauplan kann korrekt umsetzbar sein. Das heißt,
ich kriege eine korrekte Anleitung, wie ich eine Maschine zu bauen habe.
Aber die Maschine, die rauskommt, ist komplett unsinnig.
Das kann irgend sowas Absurdes sein, wie das hier. Das ist ganz wichtig,
dass ihr euch darüber im Klaren seid,
dass wir hier gerade so eine Art Maschinenbau machen in SE1. Ihr werdet also bisher wenig damit konfrontiert,
wirklich echte Probleme zu lösen, wo ihr dann abbilden müsst,
wie man diese Probleme dann in den Computer abbildet,
sondern wir sagen euch erstmal nur,
hier sind die ganzen Zahnräder,
die es so gibt,
in der Größe und in der Stärke
Und wenn ihr die zusammensetzt, dann rattern eure Maschinen so und so.
Das heißt, ihr lernt bei uns hier quasi Maschinenbau für Computermaschinen.
Und das ist eben halt dann gut,
wenn ihr diese einzelnen Bauteile auch alle sehr gut kennt.
Das ist die Voraussetzung, dass man hinterher dann auch kompetent
reale Probleme lösen kann. Okay, das nur so als
so einen kleinen Vergleich, Metapher, Programme und Maschinen.
Heute geht es um Objektsammlung. Ein sehr dankbares Thema,
was ihr heute lernt, ist extrem nützlich für fast jede
Programmieraufgabe,
die ihr lösen wollt
Ihr werdet fast immer irgendwie größere Mengen von gleichartigen Objekten
zusammenfassen und dann irgendetwas mit diesen Zusammenfassungen tun wollen.
Ihr werdet die vielleicht irgendwo weitergeben wollen oder ihr werdet auf
jedem Objekt in einer solchen Sammlung irgendwas anwenden wollen.
Das heißt, in jeder Programmiersprache, in jeder vernünftigen Programmiersprache
gibt es irgendwie etwas, womit man Sammlungen manipulieren kann.
Und auch Java bietet da was, nicht in die Sprache integriert,
aber immerhin in der Standardbibliothek und das gucken wir uns heute ein bisschen an.
Man kann sich Objektsammlungen so auf zwei Arten angucken.
Ihr habt ja schon gelernt, es gibt sowas wie
die Schnittstelle von einer Klasse oder an einem Typ.
Und das, was ein Klient so damit machen kann und
man kann sich auch angucken, wie es denn implementiert.
Und wir wollen uns zuerst mal hier den Umgang mit Sammlung angucken.
Das heißt, wir wollen sie benutzen. Wir wollen als Klienten
auftreten von Sammlung. Und damit das nicht ganz so trocken ist,
habe ich hier mal eine Webseite mitgebracht,
habe ich mir heute Morgen zusammengeklickt, hahaha, nein,
die kennt ihr, das ist Spiegel Online.
Ich weiß nicht, ob ihr das schon mal gesehen habt,
dass auf so einer Webseite ganz viel Text steht.
Also wenn ich zum Beispiel hier diesen Text mir angucke,
dann sehe ich da relativ viel Text.
Also hier zum Beispiel diesen Text hier,
den kann ich mir ja mal genauer angucken.
Also jetzt kann ich, sagen wir, interessiert sein,
daran auszuwerten, wie die ihre Texte so schreiben.
Das heißt, ich möchte jetzt diese Texte Computer verarbeitbar machen.
Okay. Eine ganz einfache Möglichkeit ist, ich kopiere diesen Text
jetzt hier einfach mit Steuer und C und speichere denen eine Datei.
Dann habe ich einen Text in einer Datei stehen.
Das kann ich hier ja ohne weiteres machen.
Das kennt ihr. Ich habe das tatsächlich hier in so
einem Projekt schon gemacht. Also ich habe hier einen Analyse-Text,
das ist irgendein Text über Ja,
habe ich irgendwann mal auf Google, auf Google Online,
auf Spiegel Online rauskopiert und in diese Datei geschrieben.
Einfach direkt reingeschrieben. Oder hier gab es vor ein paar
Jahren einen Text zu einem gewissen Herrn von Guttenberg.
Auch mit Copypasta gemacht. Und hier gab es einen langen Text.
Das ist ein relativ langer Text über die Finanzkrise.
So, das sind also einfach Texte erstmal hier.
Wenn ich das jetzt irgendwie verarbeiten will, dann muss ich mir überlegen,
wie bilde ich denn das jetzt ab auf etwas,
was ich verarbeiten kann?
Möglicherweise in einem Dava-Programm. Und der erste Ansatz,
den man hier machen muss, ist,
sich zu überlegen, dass so ein Text einfach eine Folge
von Wörtern ist
Das heißt also hier, das erste Wort ist zu,
das zweite Wort ist den und so weiter.
Ein Text ist einfach eine lange Sequenz von Wörtern.
Das nächste, was man sich überlegen kann, ist,
da kommen manche Wörter mehrfach vor.
Außerdem ist die Reihenfolge ziemlich relevant. Also in welcher Reihenfolge,
die Wörter da stehen, das prägt den Sinn des Textes.
Und es ist keine Überraschung, dass zum Beispiel das Wort
mit hier steht und dann auch nochmal hier mitsteht.
So, Worte kommen doppelt vor. In Informatikterminologie ist das
eine Liste von Wörtern. Da komme ich gleich genauer drauf,
was eine Liste ist
Wenn ich jetzt diese Texte analysieren will, dann ist es natürlich,
gut, dann habe ich da so eine Liste von Wörtern,
spannend, spannend, aber was spannender wird,
wenn ich mir überlege, was ist der Wortschatz,
der verwendet wird?
Also wie viele verschiedene Wörter benutzen die in so einem Text? Ah,
das kann dann so für Literaten ganz interessant sein,
aber wenn man dann jetzt anfängt, so verschiedene Texte herzunehmen,
zu sagen, okay, ich bitte mal die Schnittmenge der Wörter in den beiden Texten.
Dann habe ich wahrscheinlich die ganzen Füllwörter da in dieser Schnittmenge drin.
Und dann kann ich ja vielleicht diese Schnittmenge abziehen von
den Wörtern in dem einen Text,
dann habe ich nur noch die signifikanten Wörter in dem einen Text drin.
Und plötzlich kann ich vielleicht relativ schnell erkennen,
worum es in dem Text geht und was so
die zentralen Begriffe sind
Das ist erst mal so der fachliche Gedanke, also so Textanalyse,
das könnte man doch eigentlich so mit Informatikmitteln ganz gut machen.
Und wir werden uns das jetzt mal ansehen. Und was wir uns dazu ansehen,
sind zwei sehr zentrale Sammlungstypen, nämlich Mengen und Listen.
Wir sind total zentral. Und was ich schon angedeutet habe,
ist hier eine Liste, was hier unten so angedeutet ist,
das ist eine lineare Sammlung von gleichartigen Elementen.
Eben hatten wir eine Landsammlung von eine Liste von Wörtern oder
von beliebigen Werten, in denen ein Element mehrfach vorkommen kann
, haben wir gesehen
Und die Reihenfolge ist natürlich auch relevant hier. Da kann ich auch tatsächlich
irgendwie bewusst manipulieren, wenn ich auch so einen Text schreibe,
dann füge ich ein Wort irgendwo ein oder verziehe es nach vorne oder ähnliches.
Demgegenüber gibt es auch sowas wie Mengen, habe ich eben schon auch angedeutet,
so einen Wortschatz, will ich eigentlich nur wissen,
wie viele verschiedene Wörter sind denn in so einem Text drin,
dann betrachte ich die Wörter eines Textes als eine Menge.
Und da ist es so, wir haben erstmal keine Ordnung,
also die Menge der Wörter in einem Text hat nicht unbedingt eine Ordnung,
man kann das natürlich schon irgendwie versuchen,
aber es gibt ja dann ein Wort,
das an mehreren Positionen stehen kann,
also es ist da mit der Ordnung relativ schwer schon fachlich.
Und auf jeden Fall ist es so,
dass in einer Menge jedes Element nur einmal
vorkommen kann
Gut, das kann man in der Informatik sehr unterschiedlich betrachten.
Es gibt da wirklich sehr, sehr unterschiedliche Ansätze.
In der theoretischen Informatik ist es häufig so gemacht worden,
dass man Listen ansieht als ein Konstrukt, das rekursiv definiert ist.
Nämlich in dem Sinne, entweder ist eine Liste leer,
da ist kein Element drin.
Oder ich habe ein Element mit einer Liste dahinter.
Oder ein Listenelement gefolgt von einer Liste.
Das ist eine sehr mathematisch gut greifbare Betrachtung,
deswegen in der theoretischen Informatik
auch sehr beliebt
Und was man eben halt auch mit Listen häufig macht,
ist, dass man sie sequenziell durchläuft,
um irgendeine Operation auf jedes Element anzuwenden.
Auch das passiert in der funktionalen Programmierung zum Beispiel auch sehr viel.
Dieser Listenbegriff ist sehr zentral in der funktionalen Programmierung. Gut,
wir sind nicht in einer Veranstaltung über funktionale Programmierung,
sondern wir gucken uns jetzt, wie ich schon gesagt habe,
primär erstmal wieder in der Umgang mit einer Liste ist.
Also was will man eigentlich mit einer Liste üblicherweise tun?
Wie tritt man als Klient an der Liste auf?
Das ist ja ein ganz blödes Beispiel. Wir haben hier
eine Liste von Strings, die wir jetzt mal verstehen wollen
als die Namen für die Einteilung der Pausenaufsicht in einer Schule.
Also irgendwie große Pause, kleine Pause,
morgen große Pause, morgen kleine Pause, keine Ahnung.
Irgendwie so eine Reihenfolge. Dann ist klar, dass die
einen Index haben. Nun ist es in der Informatik so,
dass wir gerne bei null anfangen zu indizieren.
Das heißt, das erste Element hat den Index null.
Das habt ihr schon gemerkt bei den Strings. Da muss man
sich schon irgendwie dran gewöhnen. Das ist so ein,
sagen wir, ein Bruch zur Realität,
an den ihr aber in der Informatik nicht vorbeikommt.
So, jetzt ist es aber so,
wenn ich jetzt so eine Liste habe und die Liste auch
als etwas Veränderliches ansehe,
also so ein Listenplan ist ja veränderlich
Nur ein Dokument, damit irgendwie Leute sich irgendwie einigen können,
wer jetzt die Pausenaufsichten macht. Und jetzt stellt sich irgendwie
raus, oh, ich muss jetzt mal irgendwas ändern.
Ja, jetzt stellt sich raus, ich will an der zweiten Position jemanden reinschieben.
Also irgendwie nehme ich das Ding her und schiebe die hinten irgendwie ein weiter.
Und Jan macht jetzt dann irgendwie die kleine Pause heute.
Das heißt, der ist jetzt an zweite Position reingewandert. Relativ trivial,
was euch wahrscheinlich jetzt auch aufgefallen ist, ist,
dass jetzt Paul, der vorher an Listenindex 1 stand,
jetzt an das Index 2 steht.
Also alle Elemente haben jetzt einen höheren Index. Das ist
einfach erstmal, was man sich so klar machen muss.
Genauso kann ich natürlich auch wieder sagen, ich schmeiße jemanden raus,
Peter hat jetzt schon heute die große Pause,
da muss er nicht in zwei Tagen oder zwei Tagen schon wieder eine Pausenaufsicht machen.
Also will ich den Peter da wieder rausschmeißen. Also schmeiße
ich hier den Peter raus und dann ist er da in der verkürztensten.
Und wir haben wieder andere Indizes für die Elemente,
weil natürlich man immer, wenn ein Element gelöscht wird,
die ganzen Elemente nachrücken.
Das ist eine bestimmte Sicht, wie man mit Listen umgehen kann,
wenn man sie als etwas Veränderliches ansehen.
Das ist die objektorientierte Sichtweise auf Listen.
Mengen wollen uns auch ansehen. Eine Menge ist eine Sammlung
von Gleichhaltigen Elementen. Jedes Element kann nur einmal vorkommen
Es gibt auch Begrifflichkeiten, bei denen dann das erweitert wird.
Und man sagt, man kann auch Elemente mehrfach drin haben,
dann spricht man von einem Back oder einer Multimenge oder Mehrfachmenge.
Das sind auch Begriffe, die in der Mathematik eine Rolle spielen.
Ihr werdet auch in der diskreten Mathematik mit diesen Begriffen sicherlich umgehen.
Und dann kennt ihr sicherlich auch diese bekannten mathematischen Mengenoperationen.
Also ich füge ein Element ein, ich entferne ein Element,
ich prüfe aber ein Element enthalten ist.
Und dann gibt es so diese Mengen theoretischen Geschichten,
Mengenvereinigungen, Schnittmenge, Mengendifferenz und ähnliches.
Okay, auch da will ich jetzt eigentlich
nochmal wieder auf den Umgang mit einer Menge schauen
Und das Beispiel habe ich eben schon eingeleitet, also das
war diese Sache mit der Textanalyse. Ich habe gesagt,
einen längeren Text können wir als eine Liste von Wörtern ansehen.
Jetzt wenden wir mal diese Begriffe etwas konkreter an,
also eine Liste von Wörtern.
Wir können ja auch als eine Menge von Wörtern betrachten,
wenn uns primär interessiert, welche Wörter wirklich verwendet werden.
So, das habe ich jetzt tatsächlich auch mal hier als BlueJ-Projekt vorbereitet.
Im Moment, der kommt da wieder hier nicht raus.
Okay. BlueJ. Ich habe eine Klasse,
die nennt sich Worteinleser
Die liest aus einer Textdatei. Diese Textdatei habe ich eben
schon gezeigt, da mit diesen Texten aus Spiegel Online.
Die liest aus einer Textdatei einfach ein. Können wir
uns mal kurz angucken, wie das Ding aufgebaut ist.
Also hier, die hat eine Methode, einlesen aus Datei.
Ich gebe den Stringen als dringend den Dateinnamen an und
es wird übergeben, eine Liste von Strings.
Okay, eine Liste von Strings. Und in diese Liste
werden dann die Wörter eingelesen, die in der Datei stehen.
Also das ist eigentlich erstmal ganz einfach. Man kann sich
auch mal angucken, wie es gebaut ist.
Da wird irgendwie mit einer Wahlschleife hier irgendwie Zeile eingelesen.
Das Entscheidende ist, dass hier, Wild, Zeile,
Reader, Readline ungleich night, also solange ich noch eine Zeile einlesen kann,
wenn die Zeile größer ist als null.
Also wenn da mehr noch was drinsteht, dann verarbeitet die Zeile.
Hier wird also diese Zeile irgendwie übergeben und die Wortliste wird auch übergeben.
Das ist also das, was hier als Parameter kam.
Da oben, die Wortliste ist der Parameter. Die Idee ist,
dass man das als Klient jetzt so benutzt,
dass man eine leere Liste reinreicht und dann Dateinamen angibt und
dann kriegt man hinterher so, ist dann in dieser Liste,
sind dann die ganzen Wörter drin des Textes.
So, dieses verarbeitete Zeile sieht hier so aus,
dass es einfach nur, dass wir es mal kurz gesehen habt,
also erstmal wird hier jede Zeile, die hier untersucht wird, aufgesplittet.
Hier gibt es die Methode Split,
die ist in String definiert, die splittet an bestimmten Zeichen.
Den Zeichen kann man hier angeben, also an irgendwelchen Zeichen,
die als Leerzeichen angesehen werden können, Tabs und Ähnliches.
So, und das Ganze wird auch noch dann in kleinen Buchstaben umgewandelt.
Und dann ist es tatsächlich so, da hat man ein Array von Wörtern.
Rays kennen wir noch nicht, nicht so wichtig, kommt nächste Woche.
So, und dann geht man mit einer Vorschleife hier,
kennt ihr auch noch nicht, kommt heute, erweiterte Vorschleife,
gehe ich jetzt durch diese Wörter alle durch.
Also sozusagen das, was ich jetzt so aufgespalten habe von jeder Zeile,
die Wörter, gehe ich jetzt einzeln durch.
Und dann schmeiße ich noch bei den ganzen Wörtern die ganzen Sonderzeichen raus.
Also eigentlich schmeiße ich die Satzzeichen raus,
die so in deutschen Texten so drinstehen,
sie mit Cola, ein Ausrufezeichen,
Punkt,
Komma und so weiter
Die werden hier alle rausgeschmissen, durch nichts ersetzt, replace all,
also das, was das erste, durch das zweite.
Und dann werden diese, wird das entsprechende Wort in die Worteste eingeführt.
Das ist schon alles, was wir brauchen.
Das ist ein Dienstleister, den wir benutzen.
Ein Wort, ein Leser. Was wir jetzt uns ansehen,
ist der Textvergleicher, der jetzt so ein bisschen das macht,
was ich so angedeutet habe.
Also was macht er erstmal? Hier gibt es eine Methode
Einlesen, Dateinahme und dann hier die Wortliste.
Und dann benutzt er hier diesen Worteinleser.
Mehr passiert da nicht und zeigt dann auch an,
wie viele Wörter denn da drinstehen in dem Text. So,
und das Eigentliche, was ich hier gleich ausführen will,
ist die Methode Staat, die hat hier erstmal eine Liste von Strings,
die soll jetzt hier repräsentieren, den langen Text.
Das heißt, hier wird dieser Einleser aufgerufen,
also hier langer Text wird dann in dieses, in diese Liste eingefügt.
Und was man hier sieht ist,
das ist der Typ der Liste, eine Liste von Strings,
gucken wir uns auch noch genauer an.
Und was hier benutzt wird, ist eine Implementation dieses Typs.
Wir haben ja schon gesehen, also Liste ist eine Interface,
habt ihr schon mal gehört. Und es gibt da auch
eine Klasse, die dieses Interface implementiert, nämlich eine Arraylist.
Okay, das ist eigentlich schon mehr oder weniger alles,
was man verstehen muss. Hier wird sozusagen in dieser Variablen
stehen jetzt die ganzen eine Referenz auf eine Liste von diesen
ganzen Wörtern in dem Text.
So, und dann, jetzt passiert hier was ziemlich Spezielles.
Jetzt habe ich nämlich hier ein Set von String.
Ja, und das nenne ich hier großer Korpus.
Korpus ist so ein Begriff für den Wortschatz,
also die Menge der Wörter in einem Text.
Und bei dem langen Text ist er halt relativ groß,
vermute ich mal. Und ich benutze auch hier wieder eine
Implementation für das Interface Set, nämlich ein Hash Set.
Und übergebe als Konstruktorparamate den langen Text. Das heißt,
ich stecke jetzt einfach eine Liste von Wörtern
da rein in den Konstruktor einer Menge
Und was da passiert, ist ziemlich viel Magic.
Es werden nämlich jetzt alle Wörter aus der Liste in die Menge eingefügt,
aber natürlich unter der Regel, dass keine Duplikate eingefügt werden.
Das heißt, hinterher hat man nur noch die ganzen verschiedenen Wörter in der Menge.
Und dann kann man hier mit System Outprincial einfach ausgeben,
wie groß das Ding ist, wie viele verschiedene Wörter in dem Landtext sind.
Also das ist, glaube ich, so erstmal das,
was man hier sehen kann,
das kann ich jetzt einfach mal ausführen, das ist relativ unspektakulär.
So, ja, also einlesen von langer Text,
das sind 20.000 Wörter,
also der Text ist 20.000 Wörter lang und es sind 5.000
verschiedene Wörter in dem langen Text
Das ist jetzt noch nicht sonderlich, sagen wir,
hochwertig diese Analyse, weil jetzt verschiedene Beugungen desselben Wortes,
plural, singular sind natürlich irgendwie als verschiedene Wörter aufgefasst,
weil wir hier jetzt nicht irgendwie Intelligenz anwenden,
sondern einfach nur einfach nur das Drinks verarbeiten.
So, ja, okay, soweit so gut.
Jetzt mache ich das Gleiche mit einem anderen Text. Also ich mache mir eine weitere Liste,
variable Analyse-Text, das ist jetzt der kürzere Text,
das war der mit diesem Erdöl irgendwie,
das Gleiche wieder einlesen, den Korpus lasse ich mir geben,
Also machen wir eine Menge mit den ganzen Wörtern in dem Text
und gebe das auch aus.
So, das kann ich jetzt hier auch mal eben ausführen,
dann kann ich das auch mal eben hier noch mal ausführen.
So, jetzt sehen wir, der kürzere Text ist deutlich kürzer.
Das sind nur 664 Wörter und es sind 384 verschiedene Wörter.
Also wenn ich jetzt diesen kurzen Text irgendwie analysieren will,
dann sind 384 Wörter immer noch ganz schön viel.
Ich könnte ihn einfach lesen, das wäre das Einfachste.
Klar, aber wir sind ja hier dabei,
jetzt unseren Computer was beizubringen und der ist ziemlich blöd.
Der kann nicht
den Text verstehen
So, 384 verschiedene Wörter. Jetzt war ja die Idee vorhin,
jetzt könnte ich doch einfach mal so die Schnittmenge bilden,
der Wörter an den beiden Texten, dann kriege ich die Füllwörter.
Und diese Füllwörter ziehe ich dann ab von den 384 Wörtern.
Dann bleiben vielleicht nur noch ein paar hundert signifikante Wörter über.
Das ist die Idee. Okay,
das ist auch tatsächlich das, was ich hier gemacht habe.
Also hier habe ich das schon mal vorbereitet.
So, also Schnittmenge. Das ist einfach ein Hashset.
Da stecke ich hier schon gleich im Konstruktor,
den großen Korpus rein. Und dann mache ich hier Schnittmenge,
Retain all,
also Retain
Heißt, behalte alles das, was auch in dem anderen drin ist.
Also diese Schnittmenge hier ist ja erst mal nicht die Schnittmenge,
sondern es ist einfach nur der große Korpus.
Und der soll alle Wörter behalten, die auch in dem anderen Korpus drin sind.
Dann kommt hier irgendwie raus, Schnittmenge beider Texte,
also Anzahl der Füllwörter, ist dann irgendwie hier Schnittmenge.size.
Also man kann sich, das habe ich gar nicht gesagt,
mit Size, die Anzahl der Elemente in einer Sammlung ausgeben lassen.
Okay. Ja, und dann ist das hier dann nochmal relativ einfach.
Nochmal mache ich dann relevante Wörter. Und da sage ich jetzt,
von diesen, das sind die Wörter aus dem Analyse-Korpus,
also die Texte, die ich analysieren will, diese 384 Wörter.
Von dem ziehe ich jetzt ab, remove all,
alles das, was im großen Korpus ist.
Ich sehe gerade, ich ziehe hier gar nicht den großen Korpus ab.
Ich hätte auch die Schnittmenge abziehen können. Macht aber keinen großen Unterschied.
Naja, macht vielleicht doch einen Unterschied, ist egal.
Auf jeden Fall habe ich dann sozusagen nur noch die relevanten Wörter.
Dann sehe ich hier, wie viele Wörter das sind.
Auch das kann ich mal eben ausführen
So. Okay, jetzt sehe ich also hier relevante Wörter,
sind irgendwie kurzer Text minus langer Text, 177.
Jetzt könnte ich diese 177 Wörter mir auch schon mal ausgeben lassen.
Da gibt es sowas wie eine erweiterte Vorschleife,
die wir uns heute ansehen werden, wo ich einfach sagen kann,
gib mal alle Elemente der Menge aus.
Was ich jetzt noch ein bisschen mehr gemacht habe,
und das ist jetzt eher so, ja,
bis jetzt das, was in den Übungen machen werdet,
Mengen und Listen und so weiter.
Jetzt wird es ein bisschen advanced. Jetzt benutze ich Maps
. Das ist nur was für diejenigen von euch,
die so ein bisschen Gourmet-mäßig unterwegs sind.
Da werde ich nämlich jetzt hier, bilde ich eine Menge,
die das Auftreten von den Wörtern zählt.
Also ich, die relevanten Wörter in dem Analyse-Text,
ich weiß jetzt nicht mehr genau, wie das hier genau war.
Auf jeden Fall kriege ich dann eine Abbildung von Strings auf ihrer Häufigkeit.
Also wir, also praktisch für jeden Wort in dem Text,
wie häufig er in dem Wort in dem Text vorkommt.
Dann habe ich ja noch eine andere Map,
die abbildet von der Häufigkeit auf die Wörter,
die dann dann so häufig auftreten.
Und das schreibe ich auf die Konsole. Das will ich euch
jetzt nicht ausführlich erklären. Das ist schon ein bisschen advanced,
aber nur, dass ihr mal seht,
was man so für nette Sachen machen kann
Relevante Wörter, 177, die häufigsten vorkommen,
sind hier, neunmal kommt dieses Wort Aquiniaga vor,
sechsmal kommt Öl vor, das viermal kommt Äquador,
Erdöl und Regenwald vor, dreimal Verzicht, Atmosphäre,
zweimal Quitokohlendioxid erspart.
So, das finde ich schon irgendwie spannend. Jetzt habe
ich es irgendwie ganz banal, wirklich so einen Algorithmus angewendet,
der das alles so ein bisschen zusammendampft.
Und jetzt kriege ich hier sehr stark die signifikanten Wörter eingedeutet.
Also ich habe noch gezählt, wie häufig sie vorkommen und ähnliches.
Das einfach nur mal, dass ihr das mal gesehen habt,
hier ist noch ein bisschen was zu Maps,
also Abbildung von Schlüsseln
auf Werte
Wie gesagt, könnt ihr euch in Ruhe angucken.
In diesem Fall war das halt so,
ich hatte eine Abbildung von Wörtern auf ihre Häufigkeiten.
Das war also eine Abbildung von String of Intager.
Und eine Abbildung von Häufigkeiten auf Mengen der Wörter mit der jeweiligen Häufigkeit.
Also von zwei abgebildet auf eine Menge von Wörtern,
die zweimal vorkommen und so weiter.
Das ist der Hintergrund. Das ist so ein bisschen Motivation
. Jetzt geht es um Listen und Mengen, objektorientiert.
Jetzt gucken wir uns an, wie das hier in SC1 funktioniert.
Wir betrachten Sammlungen zustandsbasiert. Das heißt,
diese Mengen und Listen sind schon mal eigenständige Objekte.
Ich kann, habt ihr gerade gesehen im Quellti,
es kann eine Menge und eine Liste erzeugen,
die ist erst mal da als Objekt.
Ich habe eine Referenz drauf, ist leer,
kann ich was reinfügen und so weiter. Deswegen ist eine
ganz gute Verständnis auch, dass man die Dinger wieder als Behälter ansieht.
Eine Menge ist ein ungeordneter Behälter und eine Liste ist eben
halt auch etwas, wo man dann Elemente einfügen kann,
aber da tatsächlich auch Positionen Einfluss nehmen kann.
Gut, bei Sammlungen im Java-Umfeld spricht man
üblicherweise von Collections und eine Sammlung ist ein Objekt,
das eine Gruppe von anderen Objekten zusammenfasst
Werden verwendet, um, habe ich schon erzählt,
Dinge zusammenzufassen, vielleicht gesammelt weiterzugeben, gemeinsam zu manipulieren.
Was ganz wichtig ist, in so einer Sammlung ist es üblicherweise so,
dass die Elemente alle vom selben Typ sind.
Das heißt, ich habe eine Menge von Konten oder ich habe
eine Menge von Wörtern oder ich habe eine Liste von Personen oder ähnliches.
Begräft, gebräuchliche Begriffe für Sammlungen sind auch Behälter und Container.
Hier ist mal so angedeutet, wie so eine Sammlung in Java ungefähr aussieht.
Das Rote ist die Sammlung. Das Grüne sind die Elemente,
die in der Sammlung drin sind.
Und da sehen wir schon wieder, ja, aufgepasst.
In der Sammlung sind keine Objekte,
sondern in der Sammlung sind dann wieder nur Referenzen auf Also
auch hier holen uns die Referenzen wieder ein.
Ohne die kommen wir ja nicht aus in Java.
Jetzt noch so ein paar Begriffe zur Sammlung. Erstens die
Dinge, die wir da reinpacken in so eine Sammlung.
Die nennen wir Elemente. Einfach einfach als Terminus-Technikus, den wir hier verwenden.
Der Typ, der enthaltene Elemente ist, der Element-Typ.
Also bei einer Sammlung von Strings ist der Element-Typ dann String relativ einfach.
Dann gibt es den Begriff der Kardinalität. Das ist einfach ein Begriff für,
wie viele Elemente sind denn in der Sammlung enthalten?
Das ist ein ganz interessanter Punkt. Die Sammlung,
die ihr jetzt hier kennenlernt, Und das ist ein Riesenvorteil.
Das ist auch der Grund, warum wir sie euch vor
den Arrays beibringen. Rays sehen wir auch als wichtig an,
solltet ihr kennenlernen, aber wenn ihr Probleme lösen wollt,
so fachlicher Art, wie hier Textverarbeitung oder ähnliches,
das sind die Sammlungen, die wir euch heute vorstellen,
extrem viel mächtiger und fast immer die Sammlung zur Wahl,
die ihr ihn wählen solltet, wenn ihr was implementiert.
Unter anderem deshalb, weil man da beliebig viele Elemente reintun kann.
Die sind von ihrer Implementationsart, erlauben Sie euch beliebig viele Elemente reinzufügen.
Klar gibt es da Grenzen, wenn der Speicher des Computers vor ist,
geht es auch nicht mehr, Prinzipiell ist das unbegrenzt.
Die Arrays, die wir nächste Woche kennenlernen, die sind,
haben die Eigenschaft, wenn sie erstmal erzeugt sind, dann ist ihre Größe festgelegt.
Das macht sie sehr unflexibel und deswegen gucken wir uns erstmal
die flexiblen Dinge an, die wir hier wirklich ernsthaft benutzen können.
Ein weiterer Begriff, der auch zentral ist,
ist, dass wenn wir in eine Sammlung,
insbesondere bei einer Menge etwas einfügen, was schon drin ist,
dann nennen wir das, was wir da einfügen wollen,
ein Duplikat.
Nur einfach eine Bezeichnung
Was ich letzte Woche erzählt habe, war ja,
man kann auf Objekttüten draufschauen im Sinne von, welche Schnittstelle haben Sie?
Was ist die Außensicht für Klienten? Und wie sind Sie
intern gebaut? Was ist die Insicht? Wie viele
Variablen verwenden Sie und so weiter? Das Gleiche machen wir
bei den Sammlungen jetzt für Java auch. Das heißt,
wir unterscheiden zwischen Schnittstelle, zwischen Umgang, Klientensicht und Implementation.
Und bei der Schnittstelle ist uns vor allen Dingen wichtig,
wie wird mit Duplikaten umgegangen? Wie ist die Handhabung der Reihenfolge?
Also wie verhalten sich jetzt Listen anders als Mengen zum Beispiel?
Und dann gibt es Eigenschaften, wenn man das Zeug implementiert
Da geht es dann darum, welche Datenstrukturen werden denn da intern verwendet?
Race, verkettete Listen, Kombinationen daraus, Effizienz,
wie schnell ist denn so eine Implementation? Das sind alles Fragen,
die gucken wir uns auch noch an in SE1,
aber erst so in Woche 11, 12. Ja,
das heißt, wir sind jetzt erstmal primär daran interessiert,
wie kann ich denn mit Sammlungen irgendwie sinnvolle Dinge tun?
Also die Schnittstelle interessiert mich stärker. So,
wenn wir jetzt auf den Umgang mit Sammlungen fokussieren,
dann gibt es zwei wichtige und orthogonale Unterscheidungsmerkmale.
Einmal ist die Frage, wie ist es mit der Reihenfolge
Bei so einer Sammlung kann es ja sein, dass es
gar keine Reihenfolge gibt. Bei einer Menge gibt es keine Reihenfolge.
Oder die Reihenfolge ist Benutzer definiert. In dem Sinne,
dass ich als Mensch, irgendwie in meinem Programm sagen kann,
ich möchte jetzt hier etwas an der Position haben.
Zum Beispiel, wenn ihr eine Titelliste habt,
eine Wiedergabeliste in iTunes. Und ihr sagt,
ihr möchtet jetzt einen Titel an eine bestimmte Stelle haben,
dann schiebt ihr den ja ganz bewusst an Position
3. Dann bestimmt ihr als Menschen, wo das Ding steht.
Es gibt aber auch Reihenfolgen, die automatisch festgelegt werden.
Zum Beispiel die Reihenfolge der Titel auf einem Album.
Da ist natürlich das vorgelegt,
vorgegeben durch das Album
Oder eine Playlist, die iTunes für euch erstellt, irgendwie automatisiert.
Auch automatisch. Ottogonal dazu ist dann die Frage,
wie wird mit Duplikaten umgegangen? Also sind Duplikate zugelassen?
Und wenn ich dann ein Duplikat einfüge, dann wird automatisch
die Kardinalität erhöht. Das heißt, es wird einfach,
die Menge wird vergrößert oder die Sammlung.
Oder Duplikate sind nicht zugelassen. Und das habe ich
hier mal systematisch in einer Tabelle gemacht.
Also ganz einfach. Ich habe einfach nur gesagt,
naja, einfach die Reihenfolge hier in der horizontalen und die
Art des Umgangs mit Duplikaten in der Vertikalen.
Und dann kommt man eben halt zu den verschiedenen Sammlungstypen,
die man
sich so vorstellen kann
Okay, also nehmen wir mal hier zum Beispiel die Multimenge.
Ich habe schon gesagt, sowas wie Multi-Man gibt es auch.
Da ist es so, die Reihenfolge ist erstmal irrelevant und Duplikate sind zugelassen.
Das sind jetzt relativ abstrakte Begriffe. Wer kann mir mal
irgendein konkretes Beispiel aus dem Alltag geben, was eine Multimenge ist?
Etwas, wo das ganz gut passt,
wo man sagen kann, das ist eigentlich eine Multimenge.
Hat jemand mal eine Idee für eine Multimenge?
Duplikate zugelassen, Reihenfolge irrelevant, ja. Bitte? Ah
, er sagt eine Federtasche. Okay, eine Federtasche,
ja. Die Reihenfolge der Elemente da drin ist relativ irrelevant,
gibt keine Reihenfolge oder nicht so irgendwie
Bewusst manipulierbar. Und Publikate sind zugelassen. Ja, klar,
genau. Ich kann zum Beispiel zwei Bleistifte drin haben,
die irgendwie gleich sind. Noch andere Beispiele. Ein Hausstand,
ein Obststand. Oh ja, ein Obststand, wunderbar.
Reihenfolge, üblicherweise irrelevant. Aber da sind natürlich dann
auch mehrere Äpfel da. Genau. Ich habe hier so
ein paar andere Beispiele noch, einen Scrabble-Beutel.
Ich weiß nicht, ob ihr Scrabble spielt.
Da ist so ein Beutel, da ist ein Sack mit
Buchstaben und diese Buchstaben sind mehrfach, treten mehrfach auf.
Also es gibt einfach durchaus Duplikate und die Reihenfolge ist auch irrelevant,
weil irgendwie man greift da dran und nimmt irgendeinen raus
Oder Münzen oder Geldbörse, wenn ihr an der Kasse steht,
ihr habt in eurem Portemonnaie 3-1-Euro-Stücke und ihr
müsst irgendwie 1,20 Euro bezahlen,
dann nehmt ihr das eine eins von diesen 3-1-Euro-Stücken.
Also auch das ist eigentlich etwas wie eine Multimenge.
Gut, Reihenfolge-Benutzer definiert, Publikate zugelassen. Das ist eine
Liste. Wer hat mal ein Beispiel für eine Liste?
Irgendwas Anschauliches. Ja, da oben?
Namensliste mit Nacht, bei Pabet
sortierten Nachnamen
Eine Namensliste, Alf, sortiert nach Nachnamen. Okay,
das ist so ein Beispiel, ja,
da würde ich eher sagen, wenn die,
das ist ja automatisch sortiert, nach dem Alphabet,
da gibt es also sozusagen einen Algorithmus,
nach dem man sortieren kann.
Das wäre eher dann was für die sortierte Liste.
Was ist denn, wo ist denn meine Liste?
Wo hat man denn sowas? Dass irgendwie die Reihenfolge von
einem Menschen irgendwie bestimmt wird und Duplikater auch zugelassen sind.
Ja. Eine Bestellliste. Ja, ja,
aber bei einer Bestellliste ist da die Reihenfolge üblicherweise wichtig
Würde ich sagen, ja. Ich habe hier ein Beispiel,
ja, die Playlist, also habe ich gerade gesagt,
die Wiedergabeliste, wenn ihr euch bei iTunes,
könnt ihr ja auch die Wiedergabeliste erstellen.
Und da kann auch ein Titel mehrfach drin vorkommen.
Also Duplikate zugelassen. Aber die Reihenfolge ist bewusst,
ich möchte ganz genau sagen, an welcher Stelle.
Und ein Scrabble-Wort. Also wenn ihr ein Wort dahin legt,
dann ist natürlich die Reihenfolge ganz klar definiert, aber ein Buchstabe kann mehrfach vorkommen.
Gut, dann hier haben wir schon gesagt,
das war so diese sortierte Liste von Vornamen.
Ich habe hier auch noch Messwerte. Also wenn ich jetzt eine sortierte Liste habe,
wo ich einfach regelmäßig Messwertern mit einer Messstation aufnehme,
dann habe ich möglicherweise gleiche Werte,
also es wird die gleiche Temperatur an verschiedenen Zeitpunkten gemessen,
aber in der Liste werden sie chronologisch sortiert,
automatisch eingefügt, also immer nach dem Auftreten.
Okay, Beispiele für Mengen, habt ihr mal ein Beispiel für eine Menge?
Reihenfolge irrelevant, Duplikatel nicht zugelassen. Wo ist das mal
richtig nützlich, ja? Lottozahlen. Ja, absolut richtig
. Sehr gutes Beispiel. Reihenfolge ist nicht relevant,
die werden irgendwie in irgendeiner Reihenfolge gezogen,
aber Duplikate sind nicht zugelassen,
es wäre sehr peinlich,
wenn da zweimal
die zwei liegen würde
Ich habe hier Babynamen, also wenn irgendwie junge Eltern drüber nachdenken,
wie sie ihr Kind nennen wollen und dann so Brainstorming machen,
sagen, sich so Namen an den Kopf werfen und dann irgendwie wird man auch nicht Duplikate irgendwie,
also wird man immer nur eins haben,
die Reihenfolge ist auch erst mal irrelevant.
Es sei denn, man macht dann so ein Ranking der Namen,
das ist dann, wenn die Reihenfolge Benutzer definiert wird.
Sonst noch Beispiele hier für eine geordnete Menge. Hat mal jemand eine Idee,
was ist denn mal eine geordnete Menge, ja?
Eine Sitzordnung, geordnete Menge, Duplikate nicht zugelassen, ja,
weil die Personen sitzen ja alle nur einmal da und die Reihenfolge benutzt er definiert, ja.
Ja, super
Genau, das ist eine Sitzordnung. Sehr schön.
Ich habe hier noch einen Wunschzettel. Weihnachten ist ja auch
bald. Da schreibt man üblicherweise auch keine Duplikate drauf.
Und die Reihenfolge ist meistens auch ein Ranking.
Oder Bilder in einer Galerie. Geht in eine Ausstellung.
Dann hängen auch keine Duplikate, also im doppelten Sinne.
Kein Bild hängt doppelt da und es sind hoffentlich auch keine Duplikate.
Und die Reihenfolge ist vom Kurator festgelegt. So,
und dann haben wir hier noch Reihenfolge automatisch und Duplikate nicht zugelassen.
Wer hat noch ein Beispiel? Was ist da
ein gutes Beispiel für eine sortierte Menge?
Also wo die Sortierung automatisch feststellbar ist,
wo nicht ein Mensch das entscheide,
sondern ja
Das Alphabet. Duplikate nicht zugelassen, Reihenfolge automatisch. Nee,
die Reihenfolge hat irgendjemand mal, ein Mensch hat das mal festgelegt,
dass das B nach dem A kommt.
Also das ist, also die Reihenfolge ist irgendwann mal,
ja. Eine Zutatenliste, Duplikate nicht zugelassen, Reihenfolge,
ja, die Reihenfolge ist da auch nicht so wichtig.
Eine Zutatenliste, Lebensmittel, ja, vielleicht da nochmal einen Vorschlag.
Telefonbuch. Oh, Reihenfolge automatisch, Duplikate nicht zugelassen.
Ja, wunderbar. Telefonbuch, genau. Ich habe hier
noch die Bundesliga-Tabelle
Weil das ist auch eine Publikate, gibt es nicht.
Also Werder Bremen ist nur einmal drin, leider.
Und die Reihenfolge ist halt auch automatisch festgelegt und momentan nicht
so günstig für Bremen. Ja, egal. Gut.
Sammlung in Java. Jetzt kommen wir mal ein bisschen konkreter.
Das war jetzt erst mal so ein bisschen,
damit ihr so eure Gehirnwindung mal so ein bisschen konzentriert hier auf das,
was so verschiedene Arten von Sammlungen ist, so geben kann.
Jetzt gucken wir uns das an, wie es in Java aussieht.
Es gibt das Java Collections Framework. Abgekürzt JCF.
Und das besteht aus einer Reihe von Interfaces,
einer Reihe von Klassen
Die werden wir uns noch ansehen.
Und das hat sich über die Jahre so weit etabliert,
dass es quasi wie ein Teil der Sprache ist.
Es ist nicht so stark integriert wie die Strings.
Die Strings in Java sind ja, haben wir festgestellt,
spezial behandelt. In der Syntax gibt es diese Möglichkeit,
diese Tüdelchen, diese Stringliterale anzugeben.
Die werden von der Sprache besonders erkannt. Mit dem Plus
kann ich Strings konkatinieren. Also das ist Spezialbehandlung.
Das nennt man syntaktische Spezialbehandlung für einen Typ wie String.
Die Sammlungstypen des Collections Frameworks sind so in dem Sinne
nicht Spezialbehandeln. Aber die sind schon sehr klar im Kern
der Sprache
Und wir werden uns jetzt die beiden Interfaces,
List und Set mal genauer angucken. Das sind zwei Interfaces,
die genau diese Abstraktionen, Listen und Mengen modellieren.
Was wir uns dabei jetzt ansehen, ist etwas,
was ihr schon teilweise gesehen habt.
Nämlich das sogenannte Java API. Das ist das Application-Programmer oder
Programming Interface. Das ist das, was eine Sprache an
Bibliotheken mitbringt oder auch muss nicht eine Sprache sein.
Man kann ja auch andere APIs haben von Fremdanbietern.
Das sind Dinge, die Code, der nützlich ist,
den man dann benutzen kann und wo man auch dann eine Schnittstellenbeschreibung hat,
wie er denn zu benutzen ist.
Diese Java IPI, die ist ziemlich groß. Die kommt also,
wenn man Java sich installiert, kriegt man die automatisch mit dazu.
Und die ist zergliedert in kleinere Einheiten.
Die heißen Pactures oder wir nennen die auch Pakete.
Und das wichtigste zentrale Paket ist Java lang. Das enthält
alle Klassen und Interfaces, die Teil der Sprache sind.
Gucken wir uns gleich ein bisschen genauer an.
Zum Beispiel String gehört da mit dazu
Und wenn ihr etwas aus anderen Paketen benutzen wollt,
also ihr müsst, wenn ihr Java Lang irgendwie String benutzen wollt,
müsst ihr nichts importieren,
aber wenn ihr aus anderen Paketen etwas benutzen wollt,
dann schreibt ihr üblicherweise eine Importanweisung.
Und das Java Collections Framework, das wir uns jetzt ansehen wollen,
das liegt in dem Paket Java YouTill.
Und diese entsprechenden Importanweisungen stehen immer zu Anfang einer Java Besetzungseinheit,
also Import Java YouTill Set. Was ich hier nochmal vielleicht zeigen kann,
ist, dass ich hier die Dinge auch benutzt habe.
Also ich habe hier ja in meinem Beispiel auch genau diese
Dinger stehen im Port Java YouTill List, Import Java YouTill Arraillist.
Das hier ist Ein Interface, das ist ein Interface,
das ist ein Interface und das hier sind Implementationen,
das ist die Implementation von List, das ist die Implementation von Z,
das ist die Implementation von Map, die ich hier verwende.
Dieses Import an dieser Stelle bewirkt nur, dass ich an
der Stelle jetzt hier zum Beispiel einfach List schreiben kann.
Ich könnte da jetzt auch hinschreiben, den vollqualifizierten Namen,
also der Name da oben ist ja irgendwie Java,
You Till List, kann ich so genauso übersetzen.
Ich muss also diesen Import gar nicht machen,
ich könnte überall den vollqualifizierten Namen hinschreiben.
Das ist also
nur eine Bequemlichkeit
Das heißt, der Import sorgt nicht dafür,
dass das Ding benutzbar ist,
sondern der Import ist nur eine Namensverkürzung in Java.
Ein häufiges Missverständnis. Dass das eine Importanweisung wäre im Sinne von,
nur wenn ich das importiere, darf ich es auch benutzen.
Gut, dann haben wir hier diese Java API im Java-Doc-Format.
Die gucken wir uns gleich an. Ihr habt dieses Java-Doc-Format
ja schon gesehen. In Blue Jay seht, könnt ihr
ja immer euch so diese Java-Doc-Darstellung anzeigen lassen von den Klassen in eurem Projekt.
Außerdem könnt ihr, habt ihr schon die Java-Doc-Darstellung für String
gesehen. Die Beschreibung für den Typ String
So sieht das Ding aus und was man hier sieht,
das will ich schon mal vorab sagen, hier links,
eine Liste aller Pakete. Ich würde ja sagen,
nachdem wir jetzt die Terminologie ein bisschen geschärft haben,
was ist das hier? Es ist eigentlich keine Liste aller Paketnamen,
sondern eine sortierte Menge, wolltest du gerade sagen.
Wolltest du gerade sagen, habe ich genau gesehen. Genau,
es ist eine sortierte Menge, weil es kommt natürlich
jeder Paketenname nur einmal vor und sie sind alphabetisch sortiert,
also eine sortierte Menge.
Gut, wir gucken uns mal hier das Ding live an.
Das ist die API von Java 5. Das ist ja das,
was wir mindestens hier voraussetzen. Und dann sieht man hier
diese sortierte Menge von den ganzen Paketen und ein Paket ist Java Leng.
Und in dem Paket Java Leng sind dann hier so ein paar Interfaces.
Ihr seht also auch diese API ist immer so aufgeteilt,
in welche Interfaces gibt es denn und welche Klassen gibt es denn.
Also deswegen ist es ganz gut, dass ihr Interfaces jetzt schon kennt.
Und hier sind dann unter anderem auch so Dinge wie Object,
gucken wir uns heute noch näher an, aber auch String.
Also hier der Typ String, wunderbar, dann ist hier die Beschreibung zu String.
Die Schnittstelle von String. Ja, das ist das,
was ihr hier zu sehen bekommt. Und ja,
jetzt haben wir aber natürlich Das Interface Set gucken wir uns gleich an.
Hier werden wir dann gleich uns auch angucken,
wo denn im Moment, genau live kann ich das nochmal zeigen.
Java YouTill habe ich ja gesagt, Java YouTill.
Da. Ja, das ist das Paket,
das wir uns jetzt ein bisschen näher angucken.
Da gibt es so ein paar Interfaces,
also zum Beispiel List oder Q oder Set, alles mögliche,
auch Sawted Set sieht man hier, aha.
Und da gibt es so ein paar Klassen und das sind
dann so die Klassen, die das auch teilweise implementieren.
Also zum Beispiel Hashmap habt ihr eben schon gesehen,
Hash Set und so weiter.
Also zum Beispiel hier Linked List gibt es da auch,
also so Dinge,
die offensichtlich das Listen Interface implementieren
Gut, ja, das ist das,
was ich erstmal jetzt bis zur Pause erzählen wollte.
Gibt es erstmal jetzt zu dem, was ich hier gesagt habe, irgendwelche Fragen?
Das ist ja jetzt, ja, da ist eine Frage.
Da müssen wir das da mal nennen,
ich habe jetzt nicht importiert. Er fragt, ja,
er fragt, ob man das Java-Lang-Package nicht importieren muss.
Und das habe ich nicht so deutlich gesagt.
Wo ist denn hier die Folie da? Das Wichtigste,
Packett ist Java-Lang, das sind denn alle Klassen,
die als Teil der Schwachen ist, dass du,
okay, das steht da nicht so deutlich.
Also eigentlich ist es so,
Java-Lang müsst ihr nicht importieren,
weil Java-Lang ist implizit immer importiert
Das ist, das gilt für JavaLening. Könnt ihr da mal
ein bisschen deutlicher auf der Folie stehen. Hatte ich immer
gedacht, das steht da, aber steht da nicht.
Also JavaLeng muss nicht importiert werden. Das ist doch eins.
Du musst überhaupt kein Paket importieren, habe ich eben versucht anzudeuten.
Aber alles andere, wenn du dann die Dinger einfach nur benutzen willst,
mit dem verkürzten Namen, dann musst du es importieren.
Genau. Sonst noch Fragen, sonst würden wir jetzt mal
eben fünf Minuten Pause machen. Okay, also wir haben
jetzt uns das API mal angeguckt in der Übersicht.
Jetzt gucken wir uns mal so ein bisschen die einzelnen Elemente
an, die uns primär interessieren.
Wir haben zum einen
das Interface Set
Ja, also die Abstraktion für eine Menge sieht ungefähr so aus,
das ist ja ein relevanter Ausschnitt. Das heißt,
das, was erst mal so für uns primär interessant ist,
was man hier sieht, hier gibt es zum Beispiel eine Operation Scies,
die gibt mir einfach, wie viele Elemente sind denn drin?
Ich kann auch an der Halb-Europeration, ist MT,
die sagt mir, ob die Sammlung leer ist,
ob die Menge leer ist und sowas wie Contains,
ob ein bestimmtes Objekt in der Sammlung enthalten ist.
Das sind sondierende Operationen
Und dann gibt es auch noch verändernde Operationen.
Also ich kann etwas hinzufügen oder ich kann etwas entfernen oder
ich kann auch tatsächlich alle Elemente wegschmeißen.
Ich habe mal eine Frage hier zu Size on is MT.
Ich kann doch, wenn ich wissen will,
ob eine Sammlung leer ist, könnte ich doch einfach fragen,
if, sammlung.size, gleich gleich null.
Warum gibt es noch ein SMT? Das ist doch eigentlich
redundant, oder? Warum haben die Leute sowas gemacht?
Ja. Es kann auch Nall sein
Das hilft beides nichts. Ich muss beides das Ding aufrufen,
also sowohl das Objekt ist empty oder ist Size,
muss ich beides aufrufen.
Ja, da oben? Ich verstehe kein Wort.
Das Empty ist vielleicht performanter, sagt er.
Ja, könnte sein, das könnte ein Grund sein.
Denkbar ist das. Bei Size muss ich erst die Elemente
durchzählen und bei SMT muss ich das nicht tun.
Das könnte man tatsächlich relativ leicht sich merken.
Ich denke, es hat auch ein bisschen was,
da ist noch
eine Aussage vielleicht dazu
Er hat 300 gelesen. Er sagt,
es ist einfacher zu lesen. Das ist ein Aspekt,
den ich, glaube ich, primär jetzt vermutet hätte.
Es liest sich einfach besser. Und ihr werdet,
ihr werdet sehen, je mehr Quelltext ihr zu lesen bekommt,
desto wichtiger wird euch, dass das lesbar ist.
Und so ein Vergleich mit Null, klar,
ist zwar semantisch das Gleiche, aber Sammlung ist,
Empty liest sich deutlich einfacher als Sammlung.size gleich gleich Null.
Also das ist tatsächlich etwas,
wo man für die bessere Lesbarkeit eine Operation eingeführt hat,
an der Schnittstelle, die nicht unbedingt notwendig ist.
Aber es könnte auch sein, dass es aus Performancegründen ist
Gut, was ihr hier seht, ist,
es ist ein Interface und das heißt Z und er sieht
nicht so was ganz komisches mit so spitzen Klammern.
Ja, also hier spitze Klammer E. Das ist der Elementtyp,
der hiermit modelliert wird. Eine solches Interface oder eine solche Klasse,
die solche spitzen Klammern da oben enthält im Kopf,
nennt man eine generische Klasse beziehungsweise ein generisches Interface. Das heißt,
man möchte ja nicht ein Set of Person definieren müssen und
ein Set of Konto und ein Set of String und was weiß ich,
sondern man sagt einfach einmal Set of irgendwas und dann kann ein Klient konkreten Deklaration entscheiden,
ob es jetzt ein Set-of-String sein soll oder ähnliches.
Das heißt, man gibt bei der Deklaration einer Variablen
den Element-Typ an. Man parametrisiert das. Das heißt,
das hier ist ein Typ Parameter, den man da sozusagen reinsteckt.
Das sehen wir uns hier in SE1 und SE2 nicht ausführlich an,
Generizität. Wir benutzen das einfach nur. Ich glaube,
das ist relativ intuitiv, dass man,
wenn man eine Sammlung benutzen will,
dass man dann bei der Deklaration sagen muss,
es soll eine Menge von Strings sein,
weil dann auch garantiert werden kann,
dass da nur Strings reinkommen und auch Nustrings wieder rauskommen
Okay, das ist also hier dieser generische Typ und dann kann eben tatsächlich auch zum Beispiel hier bei dem Ad,
ist dann klar, es dürfen da auch wirklich nur Strings reingefügt werden, wenn es ein Set of String ist. Okay,
Beispiel einer Setbenutzung in Java,
das ist dieses blöde Beispiel mit den Babynamen,
wie gesagt, dieser Code ist nicht ernsthaft irgendwo,
hoffentlich wiederzufinden, aber ich will einfach nur mal zeigen,
wie man so das Ding benutzen kann,
also haben wir ja schon auch in dem anderen Beispiel eben gesehen,
aber hier Set of String, Babynamen,
aber so eine Variable,
für meine Menge von Babynamen und ich benutze ein Hashset als Implementation und dann sage ich erstmal,
wie viele Namen habe ich denn,
Anzahl ist erstmal Babynamen.size,
da kommt natürlich null raus,
weil nichts drin ist
Dann mache ich hier Ad Clara at Anna, at Annika,
at Anna. Das heißt, ich rufe da irgendwie Worte
in den Raum und schmeiße die da rein in meine Menge.
Und dann, wie viele haben wir drin da?
Wir haben nur drei drin, weil Anna war beim zweiten Mal ein Duplikat.
Also hier, das Anna wird nicht eingefügt,
weil es ja schon drin ist. Dann, wenn Julia
noch nicht drin ist, dann soll Julia auch mit dazu.
Also sieht man auch hier Contains, kann ich dann feststellen,
ob etwas schon drin ist. Und dann kann ich das
auch mit entweder hinzufügen. Dann fällt mir ein, Annika,
gefällt mir nicht so gut, dann wird er wieder rausgenommen.
Und dann kann ich hier nochmal sehen, wie viele sind denn drin?
Drei und dann schmeiße ich alles wieder weg,
weil ich total unzufrieden bin mit meinen Ideen,
die ich hatte
So, nur, dass ihr einfach mal seht,
so kann man auch mit so einer Menge einfach umgehen.
Also relativ straightforward. Ich habe eben schon gesagt,
Anna wird nicht eingefügt, weil sie ein Duplikat ist.
So, das sind jetzt hier die zentralen Eigenschaften von
einer Menge in Java, also eines Sets.
Erstens definiert ein Set keine, ein Set definierte,
wow, da ist ein Schreibfehler.
Das ist selten. Nach acht Jahren immer noch Schreibfehler in
den Vorhinein. Ein Set definiert keine Ordnung der Elemente.
Also intern sind die zwar in irgendeiner Ordnung abgelegt,
aber nach außen hin ist das nicht für einen Klienten nicht sichtbar.
Die Semantik von Ed ist so definiert,
dass keine Replikate eingefügt werden können,
haben wir gesehen
Die Gleichheit, also die Frage,
ob ein Element gleich ist zu einem anderen,
was schon drin ist, wird geprüft über die Operation Equiels.
Das ist ziemlich speziell. Also diese Operation Equiels,
die haben wir schon gesehen. Wir haben gesehen,
dass man Strings nur mit Equiels vergleichen sollte.
Und also das ist auch tatsächlich hier so,
in einem Set gilt einfach. Für alle Elemente,
für zwei Elemente gilt immer, wenn die ungleich sind,
dann muss es einfach gelten,
dass es nicht gültig ist,
dass E1,
Equiels E2 ist
Und dann gibt es hier noch diese Massenoperation,
also hier so Contains all, at all,
remove all, retain all, haben wir schon,
haben wir schon so ein bisschen in Aktion gesehen eben.
Diese Operation Equals, die müssen wir uns jetzt mal ein bisschen genauer angucken. Weil,
ich kann das vielleicht mal anhand eines Beispiels machen,
wir haben ja hier Blue Jay,
waren wir im Blue Jay, da ist Blue Jay,
nochmal ein anderes Beispiel,
das kommt,
glaube ich,
auch in den Übungen vor
bei euch jetzt
Das ist ja interessant. Ist auch gar nicht wichtig,
genau, das müsst ihr ja noch implementieren.
Ich glaube, das ist ein nicht fertiges Projekt,
genau so war es. Das Ding läuft noch nicht,
aber das Entscheidende ist eigentlich hier diese Klasse Tag.
Die müsstet ihr euch mal angucken, wahrscheinlich auch für die Übung,
von daher ist es jetzt gar nicht schlecht, dass ihr hier seid,
kriegt ihr gleich ein bisschen was für die Übung mit.
Lernt immer was Nützliches in der Vorlesung, haha. So,
diese Klasse Tag modelliert einen Tag im Jahr,
einen Tag in einem unbestimmten Jahr,
das heißt ohne Angabe des Jahres selbst,
also den 1. April oder den 29. Februar oder sonst irgendwas
Da sind jetzt keine Schaltjahre berücksichtigt. Klar,
muss man wieder genauer sein, aber im Grunde genommen ist das
von 0 bis 366. Nee, von von 0 bis 365.
Also, wenn ich jetzt hier sage, gib mir mal einen Tag,
einen Tag mit der Tagnummer 30, dann ist das der 31. Januar.
Mal gucken hier, to string, 31. Januar.
Okay. Okay, und jetzt mache ich hier nochmal
ein Exemplar und das soll auch der 31. Januar sein.
Jetzt haben wir wieder so eine Situation,
wir haben zwei Objekte, das sind wirklich zwei verschiedene,
also wenn ich hier auf den Objektinspektor drauf schaue,
dann ist der eine das ist der andere.
Also wirklich verschiedene Objekte, nicht. Ihr kennt ja den Trick,
ich kann ja auch hier zwei Referenzen auf dasselbe Objekt haben,
haben wir jetzt nicht. Also wir haben tatsächlich zwei Objekte
und die repräsentieren beide den Tag, 31. Januar. So,
wenn ich jetzt hier einfach mal frage, Tag 1,
gleich, gleich, Tag 2, dann vergleiche ich ja die Referenzen.
Was würdet ihr jetzt erwarten, was da rauskommt?
False, klar. Die Referenzen sind ja verschieden,
sind ja verschiedene Referenzen gemacht, offensichtlich. Was ist,
wenn ich jetzt sage, Tag 1, Equals Tag 2.
Was würdet ihr wünschen oder hoffen, was da rauskommt?
True, genau. Da kommt aber jetzt Falls raus.
So ein Mist. Der Witz ist,
und das steht hier auch auf der Folie, diese Operation Equals,
die wird ja in Java von jedem Objekttyp angeboten.
Das ist einfach so. Alles das,
was Java Lang Object definiert, das ist eine Klasse,
die auch in Package Java Lang steht.
Und alle Klassen, die ihr definiert im Java,
die haben automatisch alle Operationen von Object
Unter anderem auch Equals. Mit dieser Signatur.
Boulian Equals und als Parameter wird ein Object übergeben.
Irgendein anderes Objekt. Ich kann also jedes Objekt in Java
mit jedem anderen Objekt vergleichen über Equals.
Sensationell. Und ich kann eine beliebige Referenz übergeben.
Ich kann also tatsächlich auch sowas machen wie hier.
Ich kann auch jetzt sagen, Tag 1.equals.
Und jetzt übergebe ich hier
einen String
Hallo. Ja. Kann ich einfach hinschreiben. Ich übergebe
eine Referenz auf ein Objekt. Ein String ist ein String literal,
ist ein Objekt in String. Kann ich auch machen.
Kommt natürlich oft vorwärts raus, ja. Weil die natürlich
auch verschiedene Objekte sind, verschiedene Referenzen. Aber das Entscheidende ist,
die Standard-Implementation, also das, was in Java,
was man automatisch hat, wenn man nichts tut,
wenn ich eine Klasse schreibe und Equals nicht irgendwie verändere,
dann wird der Test auf Gleichheit standardmäßig abgebildet auf den Vergleich der Identität.
Das heißt, weil bei dieser Klasse hier, Tag,
Equals nicht geändert ist,
wird einfach auf Identität verglichen
Also bauen wir doch jetzt mal einen Identitätsvergleich. Herrlich,
das ist das, was wir jetzt live machen,
was ihr sowieso auch lernen sollt jetzt in den nächsten Übungen.
Also hier ist zum Beispiel das Two-String implementiert.
Jetzt baue ich hier mal ein Equins rein.
Das muss genau diese Signatur haben wie auf der Folie.
Also Public Boolian Equiels, Object und so weiter.
Pop, Public, Golian Equiels, als Parameter ein Object.
Das kann ich hier Other nennen. So,
und jetzt möchte ich dafür sorgen, dass,
wenn mir eine Objektreferenz übergeben wird, Ich zuliefere,
wenn das den gleichen Tag repräsentiert und Falls in allen anderen Fällen.
Wie mache ich das? Da kam mir mal so ein
paar Brocken an den Kopf werfen, wie ich das jetzt implementiere.
Ja, vor dem einen Objekt klein ist die, der Tag von dem Überwiegenden.
Okay, aber da steht jetzt, als Parametertyp steht der Object.
Kann jetzt irgendein Objekt sein? Ich habe gerade auch einen
String übergeben. Ja, wir können ja prüfen,
ob das Objekt Instance aus... Ah, okay,
er sagt, man kann prüfen,
ob es ein Exemplar von Tag ist.
Das machen wir jetzt mal
Machen wir mal hier IF. Other, Instance of Tag
. Dann können wir jetzt weitermachen. Ich mache es jetzt
mal ein bisschen anders. Ich sage jetzt mal,
if not other instance of tag,
dann kann ich direkt sagen, wenn das kein Tagobjekt ist,
dann kann ich nicht gleich sein zu dem anderen Objekt,
dann ist mir da irgendwas anderes untergejubelt worden,
String oder sonst irgendwas, dann sage ich einfach return falls.
Okay, also der Fall ist abgefrühstückt. Jetzt wissen wir,
jetzt wissen wir, dass Other ein Tagexemplar ist. Das heißt,
der dynamische Typ Wir wissen jetzt an dieser Stelle nachdem dieses Return nicht ausgeführt wurde,
also an dieser Stelle hier, genau hier,
wissen wir jetzt, der dynamische Typ von Object ist Tag.
Der Compiler weiß es aber nicht. Das heißt, das,
was wir jetzt hier gemacht haben, ist erstmal ein Typ-Test.
Das Nächste, was wir jetzt machen müssen, ist eine Typ-Zusicherung.
Also wir müssen jetzt den Compiler dazu bringen,
dass wir jetzt tatsächlich an diese, an die Eigenschaften von dem Tagobjekt rankommen.
Wir wollen ja eigentlich wohl nur vergleichen, ist unser,
wie heißt denn unsere Exemplarvariable hier, die heißt Tagnummer.
Das ist also dieses interne Feld mit der Tagnummer
Damit, ich will also nur wissen, ist meine Tagnummer
gleich zu der anderen Tagnummer, dann sind die Objekte ja gleich.
Aber damit ich an die andere Tagnummer rankomme,
muss ich das Ding irgendwie als Tag ansehen können.
Deswegen muss ich jetzt hier sowas machen wie,
ich deklariere mir eine Variable, Tag ist dann irgendwie der
andere Tag oder der Other-Tag, naja egal.
Und dann muss ich hier eine Typ-Zusicherung machen auf Other.
So, damit sage ich dem Compiler, ich weiß,
dass das andere jetzt ein Tag ist und du Compiler relaxt.
Normalerweise könnt ihr so eine Zuweisung nicht machen.
Ihr könnt also nicht etwas vom Typ,
von einem ganz allgemeinen Objekttyp, einem spezielleren Typ zuweisen.
Das geht nicht. Dann meckert der Compiler. Aber hier
in diesem Fall sagen wir, das kann er ruhig machen.
Und jetzt können wir den eigentlichen Vergleich machen.
Jetzt vergleichen wir einfach, ich sage ja einfach,
Return, Tag Nummer, meine eigene Tagnummer, ja.
Also das ist ja die, die ich hier habe.
Gleichgleich other tag.tag Nummer. Manche von euch sind an dieser
Stelle erstaunt, dass ich einfach auf die privaten Felder eines
anderen Objektes
zugreifen kann
Das tue ich ja hier. Ich greife ja hier nicht,
ich greife ja die Tagnummer,
lasse ich mir ja nicht über die Schnittstelle geben,
sondern ich greife sozusagen in die privaten Eingeweide rein.
Das darf ich, weil das andere Ding ist ja auch ein Tag.
Das heißt, wir befinden uns hier gerade im Quelltext
der Klasse Tag. Und dann können wir natürlich,
wir haben keine Geheimnisse untereinander innerhalb der Familie sozusagen.
Also Objekte derselben Klasse kennen sich sehr, sehr gut.
So, und hier, das ist dann,
ich hoffe, ihr habt das jetzt so schnell gesehen.
Ich vergleiche hier die beiden Tagnummern und wenn die gleich sind,
dann kommt da True raus und wenn die nicht gleich sind,
kommt da Fords raus.
Kann ich also jetzt übersetzen
Wunderbar, ich habe equal dreh defiliert. Herrlich. Traumhaft,
dann mache ich doch mal hier wieder so ein Tagobjekt.
Ah, Tagnummer 30, 31. Januar, ich mache noch eins. Nochmal 30. So,
jetzt habe ich hier zwei Tagobjekte und jetzt möchte ich,
dass Tag eins, ich kann das ja auch mal so probieren,
Tag eins, Equals, Tag zwei,
da soll jetzt doch bitte True rauskommen.
Und es kommt True raus. Herrlich. Wir machen nochmal
einen weiteren Test. Ich mache hier nochmal einen Tag,
das ist irgendwie der 1. Februar
Ist das wirklich der 1. Februar to string? Ja,
1. Februar. Und ist dann Tag 2 gleich zu Tag
3. False. Also scheint zu funktionieren. Wir haben ja
schon ausgiebig getestet jetzt hier. Gut. Alles klar.
Sehr schön. Ja. Aber jetzt kommt ein kleiner Effekt,
den werde ich jetzt noch mal eben ganz kurz demonstrieren hier.
Nehmen wir mal an, ich mache mir jetzt hier ein Set.
Also ein Set auf Tag. Ich kann tatsächlich,
und das ist ja ganz toll,
diesen Typ jetzt Tag einfach als Elementtyp für eine Sammlung verwenden
Set of Tag. So, dann mache ich jetzt irgendwie hier mein Tag-Set.
Und da sage ich mal, das ist ein,
ich muss natürlich dann hier das Volk qualifizieren, Java, YouTill, Set.
So, und das soll doch jetzt mal,
da brauche ich jetzt erst mal ein Set,
dann mache ich einfach mal New, Java,
YouTill Hash Set von Tag.
Ups. So, das deklariere ich hier und habe jetzt
tatsächlich hier mein Tag-Set. Also wenn ich jetzt Tag-Set hier
Dann habe ich eine Objektreferenz auf ein Hashset.
Und da kann ich jetzt Tage reinpacken in dieses Hashset.
So, jetzt ziehe ich mir das Ding mal hier rüber.
Mein Set. So, und jetzt werdet ihr einen interessanten Effekt sehen.
Wenn ich nämlich jetzt in dieses Set etwas hineinfüge, also Ad,
ich kann ja hier Ad aufrufen und dann wird da ein Tag eingefügt.
Jetzt füge ich mal Tag eins rein.
Und dann liefert er mir zurück als Ergebnis True.
Also ich konnte das einfügen. Okay,
jetzt füge ich weiter Tag drei rein.
Das war ja
der 1. Februar
Auch den kann ich natürlich hier in das Hashset einfügen.
Also Tag 3 wird da reingefügt und ist drin.
So, jetzt kann ich zum Beispiel mir für das Set
mal fragen, wie viel hast du denn?
Ja, Set, Size, zwei Elemente sind drin.
Zwei Tage sind da drin. So, okay, cool.
Jetzt möchte ich aber auch ausprobieren, ob das auch funktioniert mit dem Equels.
Weil das Hashset benutzt ja das Equels, um festzustellen,
ob ein Duplikat drin ist. Also, Jugendliche,
dumm, die dumm, nehme ich auch mal Tag
2. Da wäre es ja jetzt schön,
wenn er das nicht einfügen würde.
Das Dumme ist, er macht es trotzdem.
Und jetzt sind tatsächlich drei drin
Das heißt, es ist drei. Das heißt,
es ist drei, so ein Scheiß, Scheiß.
Ja, woran liegt das? Hat jemand eine Idee, woran das liegt?
Warum wird das Equiels nicht richtig verwendet von dem Hashset?
Eigentlich müsste es doch funktionieren. Wir haben doch gerade gesehen,
ich kann zwei Dinge vergleichen, wenn sie gleich sind,
als er eigentlich angesehen werden, doch extra das Ding redefiniert.
Er sagt, es sind unterschiedliche Objekte, ja,
aber das ist ja die Idee, dass trotzdem unterschiedliche Objekte,
wenn sie logisch dasselbe Objekte repräsentieren,
also dieses Equiels ist ja sozusagen für euch,
Objekte repräsentieren, den 31. Januar,
dann sollen die als gleich angesehen werden.
Deswegen, die Rede definiert er ja Equals,
damit dann so ein Hash-Set auch richtig funktioniert.
Ihr könnt es nicht wissen. Die Auflösung ist nämlich
ein bisschen gemein. Also, ihr könnt Equals redefinieren,
das haben wir gerade gemacht.
Für bestimmte Klassen ist das sinnvoll, eine eigene Definition von Gleichheit.
Dann kann man das redefinieren. Durch die Redefinition erhalten die
Klienten der Klasse ein anderes Ergebnis beim Aufruf der Operation Equals.
Das haben wir eben gesehen, wenn ich Equals aufrufe,
dann kommt da eben was raus.
Das ist auch bei String so gewesen.
Redefiniert auch Equals,
aber man muss aufpassen
Und das ist etwas, da wedel ich jetzt mit den Armen.
Das ist einfach so, das müsst ihr mir glauben.
Wir werden es aber noch erklären. Also noch in SE1,
in der Vorlesung, in zwei oder drei Wochen, dann wahrscheinlich nach Weihnachten noch weiter weg.
Aber werde ich euch erklären, warum Hash-Verfahren so funktionieren,
wie die sich hier funktionieren. Was ihr erstmal jetzt verstehen müsst,
und das ist wirklich was, was jeder kompetente Java-Programmierer wissen muss,
ist, dass Equals und Hash-Code, komische Methode, zusammenhängen.
Und zwar ist es so,
in der Klasse Object steht in der Dokumentation von Equals folgender Hinweis,
note that is is general necessary to overright the hash code method,
ever this message is overritten.
So as to maintain the general contract for the hash code method,
which states that equal objects must have equal hash codes.
Aha. Also wenn ich jetzt hier von Tag 1 und Tag 2,
die logisch gleich sind, mal Aufrufe, Hashcode,
Hashcode, dann kommt hier irgendeine Zahl raus, 24,
63, bla bla.
Und bei diesem Objekt kommt da raus, Hashcode,
50, bla bla bla.
Also es sind einfach verschiedene Hashcodes. Das heißt,
was wir gemacht haben, ist, wir haben Equals redefiniert,
aber nicht passend dazu
auch Hashcode
Das müssen wir tun. Das ist der Contract für Object.
Und das ist der Contract für alle Objekte in einem Java-System.
Und ihr könnt mir glauben, es sind schon Tage,
Wochen, Monate verschwendet worden in allen Java-Projekten auf dieser Welt damit,
dass Leute das nicht richtig gemacht haben und dann den Fehler irgendwie Monate später erst gefunden haben.
Also immer, wenn ihr Equals redefiniert,
müsst ihr den Hashcode passender zu machen.
Das heißt, das ist jetzt relativ leicht,
wir schreiben jetzt noch eine weitere Methode,
wir redefinieren auch Public in Hashcode
Das Ding soll also auch einen Hashcode liefern. So,
und was ist jetzt, wie kriegen wir das jetzt hin?
Wenn zwei Dinge gleich sind, dass sie dann auch den gleichen Hashcode liefern.
Was wäre euer Vorschlag? Was liefern wir da jetzt als Endwert?
Was wäre da jetzt mal eine gute Implementation in diesem Fall?
Bitte? Ja, einfach den Tag nochmal, genau.
Also hier sage ich jetzt einfach return. Tagnummer. Weil
die sind ja gleich, wenn sie die gleiche Tagnummer haben.
Und wenn die gleich sind, dann ist es auch klar,
dann liefern sie auch denselben Hashcode.
Das ist also eine ganz einfache Implementation.
Das ist nicht immer so einfach, aber in diesem
Fall total
So, und jetzt, und jetzt können wir tatsächlich hier sagen,
Java You Till Hashset, ja,
dann sage ich hier Taxset, da habe ich meine Objektreferenz.
So, hier habe ich das Hashset. Hier habe ich jetzt
einen neuen Tag und wieder mal eben 30 da einfügen,
ja, und noch mal 30. Ja, zack,
30. Also zweimal denselben Tag.
Also verschiedene Objekte, die aber denselben Tag repräsentieren,
ja, immer aufpassen. So, jetzt füge ich hier
den einen ein, also sage Tag eins da rein.
Jupp, das klappt. Und wenn das jetzt alles gut funktioniert,
wenn das alles wirklich so geklappt hat,
was wir gemacht haben,
dann dürfte der Tag zwar jetzt nicht
mit reinnehmen
Und dann sagt er Falls. Und so soll es auch sein,
weil es soll halt in diese Menge von Tagen,
sondern nur Dinge rein, die unterschiedlich sind, in Bezug auf Equits.
Und das muss aber mit dem Hashcoach zusammen, muss das passen.
Wie gesagt, warum das so ist, das erläutere ich noch.
Wir werden uns Hashverfahren noch ansehen in SE1. Okay,
jetzt gucken wir uns nochmal List an,
weil das ja auch ein relevantes Interface ist.
Das erste ist, das Interface-List ist genauso wie das Interface-Set,
also alle Operationen, die ja in das Headshütch-Set-Schnittstelle habt,
habt ihr auch in der Liste.
Alle Operationen wie im Set. Aber zusätzlich gibt es Index-basierte
Operationen. Das heißt, ich kann zum Beispiel sagen,
gib mir doch mal ein Element an Position 17.
Also mit einem Index kann ich zugreifen. Oder ich kann sagen,
setze doch mal an Index-Position 17 ein Element ein.
Oder füge ein Element hinzu. Hat jemand die Idee,
was der Unterschied ist zwischen Set und Ed?
Bei der Liste, ja? Bei Set,
da merkt man, man ist laut, wie benennt das Element,
wo wir immer bei Erde an der Stelle eigentlich hinzufügen und alle weiteren Eindrücken.
Ich habe das Themenwechsel eindenkt
Ganz gricks. Also besser hätte ich es nicht sagen können.
Er sagte, mit Set wird an einer bestimmten Position
das Element, was schon drin ist, ersetzt.
Und mit Ed wird ein Element an der Position eingefügt,
was dazu führt, dass alle Elemente danach um einen Index verschoben sind.
Remove gibt es und dann gibt es Index of,
also das sind alles indexbezogene Operationen und dann gibt es auch
noch Sublists und so weiter.
Beispiel an der Listbenutzung, das ist das,
was auf Folie 7 dieser Vorlesung drauf war.
Im Skript steht da irgendeine absurde Foliennummer, ich glaube 60,
aber es ist dann wirklich Folie 54 oder so,
schlecht gepflegt von mir
Also, List von String, Aufsichtsliste. Das ist also
dieses Beispiel mit dieser Pausenaufsicht, Aufsichtsliste, Size,
dann wird hier Peter, Paul, Mary, Peter, Jan hinzugefügt.
Und dann hat man aber wirklich fünf Elemente drin.
Immer, wenn ich Addaufrufe und Duplikate sind ja zugelassen,
wird die Kardinalität erhöht. Dann kann ich hier sagen,
Aufsichtsliste, Add, 1, Jan,
da wird Jan wirklich da reingeschoben an der Position 1,
wie das an dem Beispiel auch zu sehen war.
Und mit Remove kann ich hier sagen, Last Index of Peter,
also das ist auch so eine ganz nette Operation.
Ja, also wo ist denn Peter,
setzt das drin und dann wird er da rausgenommen?
Veranschaue ich das auch nur
Was ganz wichtig ist, ist, dass man Übersammlungen auch iterieren kann.
Das ist tatsächlich etwas, was ich hier auch in
dem Beispiel drin habe, hier mit dem Textvergleicher.
Da habe ich, glaube ich, hier unten irgendwo,
ja, das ist leider nicht so schön, nicht so schön.
Gut. Ach, vielleicht, wenn ich noch ein bisschen
Zeit habe, können wir das gleich nochmal implementieren.
Aber letztendlich ist es eigentlich ganz einfach, wenn ihr irgendeine Sammlung habt,
entweder eine Liste oder eine Menge, ist wirklich egal.
Hier haben wir ein Beispiel, eine Liste von Personen.
Dann habt ihr diese Variable hier Personenliste,
eine Referenz auf diese Liste
Dann könnt ihr mit einer erweiterten Vorschleife oder einer neuen Vorschleife
folgendes schreiben. Ihr deklariert eine Variable P,
die stellvertretend sein soll für das aktuelle Element in der Sammlung.
Also das ist ja eine Sammlung von Personen.
Also habe ich hier als Elementtyp dann auch Person P.
Und dieses Doppelpunkt hier liest sich für jede Person P in der Personenliste.
Mach irgendwas mit dem P. Und dann bewirkt das,
dass tatsächlich in dieser Vorschleife durch alle Elemente durchgegangen wird der Sammlung
und für jedes Element in der Sammlung wird irgendetwas hier gemacht.
Zum Beispiel Gibnamen aufgerufen
Eine sehr elegante, knappe Schreibweise,
um etwas mit allen Elementen in einer Sammlung zu tun.
Das solltet ihr euch auf jeden Fall aneignen.
Das ist etwas, was ihr immer brauchen werdet.
So, jetzt haben wir hier eine neue Vorschleife kennengelernt,
die erweiterte Vorschleife. Die ist ausschließlich Versammlungen vorgesehen. Man kann
die tatsächlich auch verwenden für Arrays, nehmen wir nächste Woche.
Das ist aber auch eine Art von Sammlung.
Wir verwenden die beispielsweise, wenn wir einheitlich eine Operation auf
allen Elementen einer Sammlung ausführen möchten. Die klassische Vorschleife,
die ihr auch in den letzten Wochen schon kennengelernt habt,
die ist immer dann geeignet,
wenn ich im Schleifenrumpf diesen Zähler brauche
Oder wenn die Anzahl der Durchläufe vor der Schlaufenausführung feststeht.
Also wenn ich wirklich genau weiß, ich möchte jetzt zehn Schleifendurchläufe machen,
dann VI gleich eins zu tenden oder was weiß ich.
Die Waldschleife sollte eher in Fällen verwendet werden, in denen
vorab unbekannt ist, wie viele Durchläufe es geben wird.
Also zum Beispiel in diesem Beispiel hier hatten wir ja diesen Worteinleser,
der einfach in einer Waldschleife Wile-Zeile, Readerline ungleich nallt.
Also solange ich immer noch nicht leere Zeilen in der Datei
habe, lese ich die ein.
Ich weiß ja nicht, wie lange diese Dateien sind.
Okay. Also nur, dass ihr so ein Gefühl dafür
kriegt, wann man welche Schleifenart verwenden sollte
Jetzt kommen wir noch zu einem letzten Punkt.
Wunderbar. Wir haben noch genau die 5 Minuten Zeit.
Jetzt gucken wir uns Rapperklassen an. Ich habe eben schon gesagt,
in einer Sammlung in Java dürft ihr nur,
dann dürft ihr nur Referenzen einfügen.
Ausschließlich Referenztypen sind als Elementtypen zugelassen. Wir können also
nur Objekte in Java Collections verwalten. Was ist,
wenn wir eine Menge von ganzen Zahlen brauchen?
Oder eine Liste von bulschen Werten? Das geht nicht.
Ihr könnt nicht ein List of Inter haben.
Oder ein Set of
Bullian kleingeschrieben
Stattdessen haben die Java-Leute sie was überlegt. Sie haben gesagt,
na gut, wenn man nur Objekte einfügen kann,
dann bieten wir einfach sowas an wie so Kapselobjekte.
Also es gibt zu jedem primitiven Typ,
das sind genau die acht, die es in Java gibt,
gibt es eine entsprechende Rapper-Klasse.
Und ich kann also jeden Elementtyp in so ein Objekt einer Rapper-Klasse einpacken.
Mit Boxing und Unboxing. Ein Wert eines primitiven Typs kann,
ich kann das tatsächlich jetzt hier hinschreiben,
hier irgendwie New,
Zack, schon habe ich eine Referenz auf ein Objekt.
Und das kann ich in meine Sammlung einfügen. Und das
ist jetzt ein Intiger. Das Ding kann ich also nicht mehr
verändern. Das repräsentiert jetzt die fünf, dieses Objekt.
Und ich kann mir jetzt den Wert geben lassen, in Value.
Wow, und schon habe ich tatsächlich fünf. Wahnsinn.
Und das ist einfach nur ein hässliches Element in Genres.
Einer der wenigen Design-Unschönheiten, dass man diese komischen Rapperklassen brauchte,
um bei Sammlungen dann auch deprimitiven Typen ablegen zu können.
Da muss man irgendwie hier ein New Intiger,
dann kann man da tatsächlich Set of Intiger.
Das heißt, der Element-Typ ist dann Intager,
nicht Int
Kann man hier das entsprechend diesen Rapper einfügen.
Und wenn ich das jetzt wieder raushaben will,
habt ihr gerade gesehen, kann ich bei dem Rapper auch aufrufen,
in Value und kriege den Wert wieder raus.
Geht genauso für Bullshit-Werte und so weiter. Weil das so hässlich ist,
haben die für Java gesagt, na gut,
wir machen da mal so ein paar automatische Umwandlungen.
Also ich kann zum Beispiel sowas schreiben, in i ist gleich 42 und integer i
Rapper ist gleich i. Ich muss also hier jetzt nichts schreiben,
irgendwie New Integer, bla bla bla.
Das macht der Compiler automatisch. Der sieht hier,
oh, das ist ein primitiver Typ, er sieht,
oh, das ist der Rapper dazu,
na dann mache ich mal automatisch so einen New Integer darum
Ja, ich kann das auch hier tatsächlich eine List von Inditure
deklarieren und kann dann einfach einen In-Ausdruck übergeben als Parameter.
Da wird dann automatisch ein Rapper-Objekt drumherum gewickelt und das ist sehr praktisch. Verkürzt es einigermaßen,
auch hier, wenn ich jetzt sage,
gib mir einfach mal den Wert des Rappers,
da muss ich nicht schreiben, iRapper.intvalue, sondern ich kann einfach sagen,
weist das zu, dass es dann ein Auto-Unboxing,
also Java verpackt automatisch und Java entpackt auch automatisch.
Da passiert also relativ viel hinter den Kulissen. Das führt zu einem lustigen Effekt,
das ist hier so als ein bisschen Folglore nochmal zu sehen,
Gleichheit, ist üblicherweise transitiv definiert, mathematisch formuliert.
Also wenn etwas gilt A gleich B und B gleich C,
dann gilt üblicherweise auch, dass A gleich C ist.
Kennt ihr. Wenn wir aber Folgendes machen,
Integer A ist gleich New Engineer 5,
Int B ist gleich 5 und Integer C ist gleich New Engineer 5,
dann weiß man,
das hier sind zwei Objekte und das hier ist eine Variale von einem primitiven Typ.
Wenn ich jetzt hier frage, ist A gleich B,
dann sagt er, ja, true,
weil er packt dann den Integer aus.
Er macht ein Unboxing automatisch und kann dann B mit
dem A vergleichen
Das macht er bei B&C genauso. Aber wenn ich dann
A und C vergleiche, dann sind das verschiedene Objekte.
Also da ist halt so ein bisschen blöd.
Also diese Rap-Pub-Dinger sind ziemlich hässlich. Also ihr müsst
ein bisschen aufpassen mit denen. So, was ich
jetzt heute erzählt habe, ging primär um Sammlung.
Wir haben heute uns Mengen und Listen angesehen. Und ich habe euch gesagt,
es gibt im Collections-Framework für Mengen und für Listen jeweils ein Interface.
Set und List. Und was ihr braucht,
also wenn irgendein Problem lösen sollt,
dann müsst ihr euch als erstes überlegen, Sind da Duplikate zugelassen?
Ist die Reihenfolge relevant? Also das ist sozusagen problemabhängig.
Dann entscheidet ihr euch für eines dieser Interfaces.
Entweder für ein Set oder für eine Liste. Und die
ganzen Variablen sollten auch wirklich von dem Typ des Interfaces sein.
Und zweitens muss man sich für eine Implementation entscheiden.
Das ist leider so. Es gibt zum Beispiel für das List-Interface,
gibt es zwei Implementationen im Gregtions-Framework. Linklist und Arraylist.
Die werden wir uns auch noch mal ein bisschen genauer ansehen.
Die sind aber eigentlich erst mal äquivalent. Das heißt,
aus Sicht der Benutzung ist es eigentlich egal, welche ihr nehmt.
Und bei Set gibt es auch zwei Implementationen,
die sind allerdings nicht ganz so leicht austauschbar.
Hashset und Treeset
Aber das ist erstmal nur, da müsst ihr einfach,
momentan könnt ihr Dinge einfach benutzen. Ihr sagt einfach,
wir nehmen immer ein Hashset und nehmt immer irgendwie ein Linklist oder Array list.
Es kommt zu Situationen, in denen ihr
ein bisschen genauer hingucken müsst, welche Implementation ihr benutzt.
Nämlich dann, wenn es um Effizienz geht. Das gucken wir
in seine SE1 hier auch nochmal ein bisschen genauer an,
wie man so unterschiedliche Laufzeiten erzielen kann mit so unterschiedlichen Sammlungen.
Gut, das ist die Zusammenfassung für heute.
Ich lese es nicht nochmal vor,
gibt es noch Fragen jetzt zu den Sammlungen,
die ich vorgestellt habe,
zu Listen und Mengen
in Java
Okay, dann ein bisschen Storesi, zum Schluss,
wir haben ja heute massig Zeit.
Folgender Quelltext. Eine Menge von Strings und ihr müsst es so,
jetzt müsst ihr sozusagen ein mentales Modell haben von dem,
was Java macht.
Was passiert hinter den Kulissen
Welche der folgenden Aussagen gelten nach Ausführung dieses Quelltextes?
Eine Aussage ist richtig. Also gilt,
dass B1 den Wert Falls hat oder hat länger Einzelwert,
2 oder hat B2 den Wertfalls oder hat länger 2 den
Wert?
2. Entscheiden Sie sich jetzt
Das ist ein klassisches Klausurbeispiel. Ja, wir manipulieren so
ein bisschen so eine Menge und da muss man verstehen,
was da passiert und dann kann man auch diese Fragen leicht beantworten.
So, jetzt mal mutig hier mit den Entscheidungen
Also mindestens 100 Stimmen möchte ich hier zusammenkriegen.
Ja. Unter Stimmen sind gut. 111, ja.
120. Okay, reicht. Gut. Wir gucken erstmal auf
die Verteilung. Okay. Das ist interessant. Also
die Mehrzahl von euch glaubt, dass B2 den Wert
Falls hat
Dann glauben, 39 das Länge 1, den Wert 2 hat.
Und dann gibt es auch noch welche, die glauben,
dass Länge 2, den Wert 2 hat.
Das ist interessant, weil das ist ziemlich erschreckend.
Das ist vor allen Dingen deshalb verwunderlich,
weil ich habe die gleiche Frage im letzten Jahr gestellt in der Vorlesung
und da war die Mehrzahl tatsächlich für die richtige Antwort.
Ich habe heute anscheinend schlecht erklärt. Wow, gut.
Also dann, was passiert hier? Das ist eine Menge
. Das ist eine Menge. Das heißt,
wenn ich hier Tisch hinzufüge, wird das Element hinzugefügt.
Stuhl wird hinzugefügt. Tisch ist ein Doplikat
Also wird es nicht hinzugefügt. Also ist länger eins, hier zwei.
Bulien B1 ist meine Menge Contains-Tisch. Natürlich enthält es denen.
Bulien B1 ist also nicht Falls, also es ist True. Meine Menge Remove-Tisch,
es waren zwei Elemente drin, Tisch und Stuhl,
Tisch wird entfernt, dann ist meine Menge, Punkt,
sei es 1, also es länger 2,
1 und nicht 2. Bulien B2 ist meine Menge Contains-Tisch,
wenn ich den Tisch einmal entfernt habe,
ist er raus.
Diesen Umgang mit einer Menge, den müsst ihr...
Das ist die Frage. C, B2 hat
den Wert Falls
Oha. Oha. Verdammt. Na gut,
habe ich euch an eurer Ehre gepackt jetzt.
Dann entschuldige ich mich jetzt. Ihr habt das richtig erkannt
. Aber das ist ja total blöd hier.
Okay,
nächste Frage
Ja. So, welche der folgenden Quelltexte sollte anstelle
der Unterstriche stehen? Also hier, ja,
damit in der Vorschleife alle Elemente der Sammlung bearbeitet werden.
Also hier wird irgendwie eine Menge von Personen übergeben und
es soll in einer Schleife hier in einer Vorschleife,
soll irgendwas gemacht werden hier mit unserem Beitrag berechnet werden.
Gar nicht wichtig, was da passiert.
Es geht nur darum, was wird jetzt hier eingesetzt.
A, B, C oder D. Was ist das
richtige Fragment, was hier einzusetzen ist
Ich also erzähle. Ich weiß auch jetzt,
woher dieser Fehler auf der vorigen Folie kam.
Das war im letzten Jahr nicht falsch. Das lag nur daran,
weil ich die umformatiert habe, so mit Copy-Paste-Fehler.
Ja, du kannst das Video vom letzten Jahr gucken,
da steht das noch so drin.
So, jetzt mal Entscheidung hier
Genau. Die erweiterte Vorschlage habe ich hier nicht live vorgeführt.
Das war nur eine Folie. Das ist vielleicht ein bisschen gemein,
aber andererseits sind ja nur so Elemente drin gewesen,
die ihr durchaus, 120 Stimmen, wunderbar.
Oh, 130, oh, ich halte das mal an.
So, mal gucken. Personen, Personen, Personen.
Ihr seid so gut. Schönen Feierabend euch.