Java 8 – Stream API

Kommen wir nun im dritten Artikel zu den etwas spannenderen und vielleicht nicht ganz so theoretischen und ersten Annäherungen, die Java8 (oder 1.8) an Neuheiten mit sich bringt – die Stream API.

Das Beispiel aus dem Artikel zu Functional Interfaces wird hierbei als Grundlage verwendet ist aber natürlich als eigenes Package java_8_class_3 im Github-Repository zu finden. Kurz zusammengefasst wird hier die neue forEach-Methode des Iterable Interfaces genutzt, um über alle Elemente der Liste zu iterieren. Statt direkt auf der Liste zu iterieren, werden wir uns im ersten Schritt einen Stream erzeugen und diesen ausgeben:

Auch wenn uns der Optimizer darauf hinweist, dass wir den Ausdruck durch Verwendung der Collections.forEach-Methode vereinfachen können, ist unser Code lauffähig und erzeugt für diese Anweisung folgende Ausgabe:

Dass dieses Beispiel nicht sinnvoll ist – klar und dass die Verwendung von Stream hier nicht notwendig ist, ist auch klar, aber werfen wir einen Blick auf folgendes Beispiel:

Folgende Ausgabe erscheint:

Wir filtern also alle Strings, deren Werte kleiner als 4 sind. Nur der Vollständigkeit halber, können wir dieses Statement auch so schreiben:

Das ganze ist nicht nur deutlich unübersichtlicher und länger, sondern ist auch in der eigentlichen Entwicklung deutlich unangenehmer.

Um den Umgang mit der Stream API zu beherrschen sollten einige Dinge bekannt sein, ohne die es wenig Spaß macht, diese zu verwenden. Beginnen wir mit drei verschiedenen Operationskategorien, die auf Streams angewendet werden können:

  1. Create-Operationen:
    • meineListe.stream() –> sequentiell verarbeiteter Stream auf Basis einer Collection
    • meineListe.parallelStream() –> parallel verarbeiteter Stream auf Basis einerCollection
    • Arrays.stream(meinArray)[.parallel()] –> sequentiell oder parallel verarbeiteter Stream auf Basis eines Arrays
    • Stream.of(String-values oder Integer-values) –> Direkte Erstellung auf Basis von übergebenen Werten
    • IntStream.range(beginInt,endEnt) –>Erzeugung eines IntStream mit Range von 7 bis 42, wobei das untere Ende des Intervals enthalten und die obere Grenze nicht enthalten ist
    • Stream<Path> kann durch die die Verwendung von Files.list() auf einem Verzeichnis etabliert werden
    • Files.lines() liest einen Stream<String> Textdatei
  2. Intermediate-Operationen:
    • filter() –> Aussortieren von Elementen auf dem Stream; Verwendung von .filter().filter() ist genauso möglich wie die Verwendung von .filter( (Bedingung).and(Bedingung))
    • distinct() –> Entfernung doppelter Einträge
    • sorted() –> Sortierung
    • skip(n) –> Überspringen der ersten n Elemente
    • limit(n) –> Begrenzung auf n Elemente
    • map() –> Mapping eines bestimmten Element(Typs) zu einem anderen Element(Typ); die Typumwandlung ist hierbei optional, wird aber sehr häufig genutzt
    • peek() –> Untersuchung des aktuellen Elements ohne ein Fortsetzen der Iteration
  3. Terminal-Operationen:
    • forEach() –> Behandlung jedes Elements des Stream
    • collect(Collectors.toList()) –> Alle Elemente des verarbeiteten Streams werden in eine Liste gespeichert
    • collect(Collectors.toMap(myElem::id,myElem::name)) –> Speicherung der aus dem Stream resultierenden Daten in eine Map<Integer,String)
    • collect(Collectors.groupingBy()) –> Gruppierung der Elemente
    • reduce() –> Reduzierung auf einen einzelnen Wert anhand des gegebenen Ausdrucks
    • anyMatch() –> Reduzierung auf einen boolschen Wert anhand des gegeben Predicates
    • findFirst() –> Reduzierung auf das erste Element gekapselt in einem Optional

Es gibt sehr viel mehr Beispiele als die, die hier aufgelistet sind. Gerade im Bereich der Collectors ist noch sehr viel Redebedarf ;-). Eine weitere wichtige Information ist, dass Streams lazy sind, das bedeutet, dass erst mit dem Hinzufügen einer Terminal-Operation die angegebenen Operationen auf einem Stream ausgeführt werden.

ZeroTurnaround hat einen brauchbaren Cheatshee für den Einstieg veröffentlicht.

Java 8 – Lambdas (Closures)

Während in Java häufig nur von Lambdas gesprochen wird, handelt es sich bei Lambdas um die in Java umgesetzte Variante von Closures, deswegen sollten wir hier einen kurzen Blick auf Closures werfen.

Was ist eine Closure? Eine Closure – ja das Wort ist feminin – ist ein Konstrukt aus der Softwareentwicklung, bei der eine Funktion Zugriff auf seinen Erstellungskontext hat – hää wie jetzt? Na gut, etwas mehr Info anhand eines Beispiels (Quelle des Beispielcodes):

In dem Beispiel (zum Github-Repository) gibt es eine Funktion make_fun(), diese hat als Rückgabe eine anonyme Funktion, hierfür ist Lambda ein Synonym, häufig fällt in diesem Kontext gerade bei JavaScript und PHP der Begriff des Callbacks. Wie zu sehen ist, kann die zurückgegebene Funktion (der Teil in den geschweiften Klammern) auf die lokale Variable n zugreifen und diese sogar verändern, obwohl sie außerhalb des eigentlichen Funktionskontextes liegt, dem sogenannten Erstellungskontext. Die Funktion make_fun hat in der Methodensignatur keinen Funktionsparameter und einen Rückgabewert vom Typ Function<Integer, Integer>, was zugegeben auch zu erwarten war, da wir eine anonyme Funktion erstellen. Ein Blick hinter die Kulissen des Typs zeigt:

Wobei T der Typ des Parameters für die Funktion und R der Typ des Rückgabewertes der Funktion ist. Die Schreibweise ist etwas gewöhnungsbedürftig für Neulinge im Feld der funktionalen Programmierung, aber nach kurzer Eingewöhnungsphase doch verständlich. Die Invocation unserer Funktion findet anschließend durch den Aufruf der apply-Methode statt. Hierbei wird die Methode auf die übergebenen Werte angewendet – beispielhaft mit 5 Werten in zwei Durchläufen.

Zu sehen ist, dass sowohl der Callback auf der Variablen x als auch auf der Variablen y ihre eigene Variable n haben (wovon wir auch ausgegangen sind), sich der Inhalt der Variablen aber nicht ändert. Sollte nun versucht werden, den Wert von n innerhalb des Callbacks zu verändern, beispielsweise durch n += arg;, so wirft der Compiler (JIT Compiler) direkt einen Fehler:

Das bedeutet, dass die in Java verfügbaren Closures in Form von Lambdas keine Variablen sondern Wert geschlossenen Closures sind (Zur Erinnerung eine Closure ist ein über Speicherstruktur und Funktion geschlossenes Konstrukt).

Wenn eine Variable verändert werden muss, kann dies durch ein auf dem Heap abgelegtes Objekt etabliert werden:

Bringen wir diesen Code nun mit unseren beiden Beispielen zur Ausführung erhalten wir folgendes Ergebnis, in dem wir auch die außerhalb der Funktion gelagerten Variablen bearbeiten können, da der Compiler hier lediglich die Änderung der Referenz innerhalb der Funktion prüft (probiere einfach, myWrapperClass innerhalb der anonymen Methode neu zu instanziieren):

Wenn man hierbei noch Concurrency-Probleme beachtet (mutable shared state), hat man durch einen kleinen Umweg genau das, was ein Closure ausmacht.

Trotzdem sind Lambdas sicherlich eine sehr sinnvolle Neuerung in Java8.

Der Programmcode kann im Github-Repository gecloned werden. Der relevante Beispielcode findet sich im Package java_8_class_2.

Java 8 – Functional Interfaces

Ich bin mir oft nicht sicher, ob der Hype um das Thema funktionale Programmierung übertrieben ist, doch ich habe erlebt, dass einige Operationen kürzer, schneller und übersichtlicher implementiert werden können und beispielsweise mit parallelen Streams auch noch schneller verarbeitet werden können – vorausgesetzt eine parallele Verarbeitung ist möglich. Zudem denke ich, dass kein Entwickler, wirklich um ein grundsätzliches Verständnis der funktionalen Programmierung drum herum kommt, da viele Kunden und Auftraggeber häufig von Buzzwords getrieben sind und der Meinung sind, dass eine moderne Software auf einem funktionalen Programmieransatz beruht – ich sehe dies wie viele meiner Kollegen etwas anders, die sagen…“Kommt drauf an“…

Doch nun genug Stimmungsmache ;-):

Im ersten Code-Snippet werden wir mit Hilfe der neuen default-Implementierung einer forEach-Methode aus dem allgemein bekannten Iterable-Interface:

In dem ersten Beispiel im Kontext Java 8 wird über eine Liste von Strings iteriert und die Char-Sequence ausgegeben. Dazu habe ich hier ein Github-Repository mit den Beispielen angelegt, über die wir hier sprechen werden. Betrachtet wird die Klasse Java_8_Class_1. Bisher verwendeten wir die in Java 1.5 eingeführte extended-Loop:

Das Interface Iterable bringt nun die forEach Methode mit, die als Parameter ein Consumer<T> als Parameter erwartet:

Die Ausgabe von Java_8_Class_1 sollte wie nachfolgend dargestellt sein:

 

Java 8 – Überblick

Oracle führt mit Java 8 (anders als bei Java 7 einige wirklich interessante Dinge ein, die nicht nur meinen Convenience-Mode triggern, sondern auch mein persönliches Interesse daran, mich damit zu beschäftigen.

Ich werde in den kommenden Tagen zu allen Neuerungen ein kleines sprechendes Beispiel in Form eines Code-Snippets posten.

Dreamhack 2016 #DHDE16

Vom 22.01.2016 – 24.01.2016 fand in Leipzig die Dreamhack Deutschland erstmalig statt. Ich möchte kurz meine Eindrücke in Kombination mit einer nachfasslich objektiven Bewertung aus Sicht eines erfahrenen LAN-Party Gängers schreiben.

Infrastruktur

Location: Die Messe Leipzig ist aufgrund ihrer modernen Infrastruktur ideal für große LAN-Partys geeignet.  Die Internetverbindung war tadellos, Downloads mit 100mbit/s und ein Ping von <30ms bedeuteten, dass das Spielen von Onlinegames problemlos möglich war. Das LAN der Veranstaltung wurde mit 100mbit/s pro Platz aufgebaut, wobei jeder 24 Port Switch einen 1 Gigabit Uplink über Ethernet und einen über SFP als Backup hatte. Hier hätte durchaus ein wenig bessere Hardware eingesetzt werden können, gerade bei der Backbone Anbindung könnte zukünftig etwas schnelleres verwendet werden (wobei es mich in diesem Jahr wenig gestört hat). Die Procurve Switche waren aber stets zuverlässig. Ein unnötiger Punkt der Organisation war die Bereitstellung von Netzwerkkabeln, wobei natürlich so mit annehmbarer Zuverlässigkeit festgestellt werden kann, welche IP an welchem Platz sitzt…was meiner Meinung nach auf einer LAN nicht notwendig ist, hierauf gab es auch keinen Hinweis im Vorhinein.
Vor Ort gab es Duschen, die zugegeben recht weit entfernt waren, aber ein wenig Bewegung tut vielen Gamern nicht schlecht. Hier kann das Video von M4DM4STER betrachtet werden, dass den Weg zu den Duschen zeigt:

Er entführt uns hier in die Katakomben der Messe Leipzig. Die Duschen waren Samstag gegen 12:00 Uhr so sauber, dass man sich nicht unwohl gefühlt hat.
Schlechter sah es hier bei der Toilettensituation aus. Es gab fünf Kabinen und sieben Stehklos auf der einzigen Herrentoilette, die direkt an der LAN-Area angrenzte. Diese wurden zu selten gereinigt – sofern dies während der Veranstaltung  überhaupt stattgefunden hat.
Die Temperatur in der Halle war in Ordnung, manchmal zog es kalt in unseren Sitzbereich in Reihe E/F hinein, was aber zumeist gut auszuhalten war. Der Sitzplatz war sehr positiv zu bewerten, immens viel Platz zwischen den Sitzreihen brachte ungeahnte Möglichkeiten mit sich!
Essen…gab es. Aber wo ist das ganze Junkfood (Burger, Gyros, Currywurst)? Ebenfalls haben Gameserver für diverse Spiele durch den Veranstalter, sowie die Option für Gastserver gefehlt. Wenige Tage vor der Veranstaltung wurden spontan fünf privat mitgebrachte Gastserver ‚erlaubt‘.

Spiele

Die Diversität der Spiele war mittelmäßig bis gut. Selten habe ich World of Warcraft gesehen, hingegen wie üblich sehr viel Counterstrike: Global Offensive, League of Legends, Battlefield 4, Heroes of the Storm und Dirtybomb. Seltener aber dennoch vorhanden Unreal Tournament Classic, Quake 3, Age of Empires 2 und Warcraft 3 und Flatout.
Der Spielbetrieb war – meines Wissens nach – von Seiten der Internet- und Netzwerkverbindung her problemlos möglich.
Das größte Manko war die immense Lautstärke aus der Messe- und Veranstaltungs-Area nebenan, was die Benutzung von Teamspeak nahezu unmöglich und Clans das Leben bei Turnieren unnötig schwer machte.

Festival ‚Dreamhack‘

Oft genug habe ich in der DiscordApp (scheinbar dem offiziellen inoffiziellen 😉 Nachfolger vom IRC) und bei Facebook in den Bewertungen der Veranstaltung gelesen (von den Veranstaltern), dass die Dreamhack ein Festival und keine ausschließliche LAN-Party sein soll.
Also, was darf bei einem Festival nicht fehlen? Essen, Kaffee, Crepes und Pizza, zwei Bars – und ein gratis Monster Energydrink – danke dafür. Preise unverschämt (Pizza26cm für 8,50€ ) – was aber zu erwarten war. Es gab Freitag Abend eine ‚XMG Aftershow Party‘, wo sich die Getränkeauswahl auf Bier und Radler einer Lokalmarke beschränkte (ich nenne sie hier nicht), die nach Angaben von Betroffenen/Konsumenten (Zitat) „so wenig schmeckt wie Abspülwasser nach einer Großveranstaltung“. Nun gut…geschenkter Gaul und so…Es gab viele Livespiele von Semiprofi- und Profispielern, was zu jeder größeren LAN-Party dazugehört, mit sehr guter Akustik und Stimmung, guten Moderatoren und einer professionellen Organisation, nur bitte lieber Organisatoren, wenn ihr in der Halle diverse Displays an eure Aussteller weitergebt, dann gebt diesen eine Kabelverbindung und streamt das Dargestellte nicht via WLAN zu den Geräten…das funktioniert nicht im 2,4GHz Band auf einer derartigen Veranstaltung.
Total bescheiden und einfach nur störend war die Eventbühne, auf der den gesamten Freitag  (bis Samstag 02:00 Uhr) elektronische Musik in immenser Lautstärke lief und auf der (kein Witz) am Samstag um 09:00 Uhr eine „Death Metal Schrei mein Publikum zu Tode“- Band mit Namen Line Arrays – ihren Soundcheck gemacht hat, was die meisten Gemüter sehr misslich gestimmt hat. Den ganzen Tag über war es unmöglich vernünftig zu Spielen oder zu streamen – achja, es gab ca. 20 Streamerplätze (genau gegenüber der Eventbühne) – wo durchaus bekanntere Gesichter wie Scissor oder Miss Rage zu sehen waren, wobei mich diese Thematik kalt lässt da ich alt genug bin, um selbst auf LAN Partys zu gehen ;-). Aussteller wie XMG, Riot, Monster, MediaMarkt und Asus waren auf der Consumer Messe mit Ständen vertreten.
Ca. 100 Cosplayer haben ihre Kreativität bei Verkleidungen und Performance gezeigt, mit teilweise mehrjährigen Kostümentwicklungen (Dreamhack Cosplay >>).

Organisation der Veranstaltung

Wie bereits erwähnt ist die infrastrukturelle Organisation top gewesen – großes Lob!
Die Organisation im Vorfeld hingegen war mangelhaft. Doch keine negative Kritik ohne Begründung: Der Prozess der Registrierung war undurchdacht, die GUI und Aufmachung der Seite war nicht stringent und wenig durchdacht, es gab keine Suche, die FAQs waren anfänglich so gut versteckt, dass diese nur mit Hilfe der allmächtigen Suchmaschine aufgefunden werden konnte. Informationen zum Ablauf, ein Loginbereich mit Forum, anständiger Support durch den Veranstalter, sowie fehlende Flexibilität bei der Sitzplatzwahl machten die Veranstaltung bereits vor Beginn zu einem Desaster, hier MUSS sich die Dreamhack Deutschland für die #DHDE17 definitiv weiterentwickeln! Facebook ist kein Ort für Support und ein nicht vorhandenes Forum durch ein fremd-gehostetes Forum bei „forumieren“ ist keine Alternative! Banner, Popups und Links auf dieser Seite verlinken auf Seiten, die von Google als unsicher, aufgrund von Malware und Phishing eingestuft werden – Liebe Veranstalter das geht gar nicht!
Die Anreise war problemlos, ideal wäre bei der letzten Ampel ein Aufsteller, der auf den offiziellen Parkplatz der Dreamhack verweist. Dort angekommen wird man in einer großen ordentlichen Messehalle freundlich von den Mitarbeiter begrüßt, bekommt Hawaii- ähnlich eine Halskette mit einem scanbaren Code drauf umgehängt und wird gefragt, wieviel Hardware man einchecken möchte. Eine Erklärung, dass empfohlen wird, jedes teure Stück Hardware mit einem Aufkleber zu versehen wunderte mich, empfohlen wurden zwei bis fünf Aufkleber, ich wählte drei – warum? – keine Ahnung, weitere Informationen fehlten. Nichts ahnend gehen wir zu unserem Platz und freuen uns über den immensen Platz….sehr gut liebe Veranstalter! Wir trugen unsere Sachen durch den Seiteneingang rein, ein netter Sicherheitsbeauftragter lies uns nach einer freundlichen Bitte durch, was den Weg um mehrere hundert Meter pro Tour verkürzt hat, auch danke dafür. Nochmal zu den Aufklebern. Am Sonntag Nachmittag zum Ende der LAN baute sich um Seiteneingang ein Team auf, die eine Kontrolle durchführten von anfänglich jeder Tasche und jeder Kiste, was mit zunehmender Dauer immer weniger wurde. Es wurde im Vorhinein keine Informationen darüber gegeben, dass alle Aufkleber wieder mit raus genommen werden müssen, die am Anfang bestellt worden sind. Diese sind mit Code auf der Karte um meinen Hals verbunden und erst wenn sämtliche Codes gescannt wurden, durfte man die Halle verlassen – wer hat sich den Mist ausgedacht? Wenn ich nun einfach nicht alle Codes brauche, darf ich diese nicht wegwerfen? Die Logik ist Nonsense, da niemand anderes mit meinen Codes die Halle verlassen kann. Der Prozess ist Mist liebe Orgas, alleine, weil ich die Codes von meinen Geräten abziehen könnte und als bereits gescannt betiteln könnte oder meinen ‚Zweitmonitor‘ nicht beklebt habe, weil ich zu wenige Aufkleber hatte… Wenn ihr so ein Vorgehen durchsetzen wollt, müsst ihr die Teilnehmer über das, was ihr macht aufklären und nicht einfach Aufkleber auf die Hardware kleben lassen (sondern es selbst machen) und dann nach einiger Zeit aufhören ordentlich zu kontrollieren.
Was mich am meisten gestört hat, war die Phrase „Wir haben es an den Projektverantwortlichen weitergeleitet“ oder „Der Projektverantwortliche hat gesagt“. Diese imaginären nicht vor Ort befindlichen organisatorischen Personen, die von 10:00 – 16:00 Uhr in der Woche Kernarbeitszeit haben interessieren den Besucher der Veranstaltung nicht, da diese nicht ansprechbar sind. Ein Projektverantwortlicher muss JEDERZEIT da und ansprechbar oder schnell verfügbar sein, alle anderen können mir als Besucher nämlich nicht helfen und in gewissem Sinne ist jeder einer Fachbereichs verantwortlich für das was seine Kollegen tun – mindestens Rechenschaft.

Fazit

In der Discordapp habe ich gelesen – Zitat: „das beste dieser Veranstaltung ist dieser Chat“Über diesen Kommentar habe ich viel nachdenken müssen, während ich diese Bewertung geschrieben habe. Ich gebe der Veranstaltung 3/5 Sterne (3,3 ist die aktuelle Bewertung bei Facebook – während die Northcon 4,25 hatte, was ich bis einschließlich 2012 unterstützen würde). Warum meine Bewertung (in fett aus meiner Sicht wichtige/schwerwiegende Punkte):
Pro:

  • Infrastruktur (Anfahrt, Netzwerk und Internet, Duschen)
  • Spielediversität
  • Platzangebot
  • Messe- und Showbühne (nicht Eventbühne)
  • Freundlicher und fähiger IT-Support
  • Professionelles und freundliches Personal der Messe Leipzig
  • Nette Aussteller
  • Toleranz bzgl. der Übernachtung in der Halle (es gab ja auch keine Alternative)
  • Es gab eine (große) LAN-Party

Contra:

  • Kein LAN Gefühl
  • Toilettensituation
  • Eventbühne und daraus resultierende unzumutbare Lautstärke
  • Organisation und Kommunikation vor und während der Veranstaltung
  • Kein Junkfood (außer Pizza)
  • Kommunikationsdifferenzen bzgl. Ein- und Auslass mit Hardware
  • Sitzplansoftware unbrauchbar
  • Kein Supportforum oder zeitnahe stattfindender Support
  • Fehlende Flexibilität
  • Keine Möglichkeit Hardware via UPS lieferbar an die Messe (auch nicht gegen Geld, wie es bei anderen LANs möglich ist)
  • Unbrauchbarer Registraturprozess
  • Fehlende Gameserver auf der LAN (BF4, Quake, UT und dergleichen sind einfach zu hosten)
  • Kein Gastserverbereich
  • Keine ruhigen Schlafgelegenheiten

Bereits durch kleine Verbesserungen können auf einfache Art und Weise diverse Dinge verbessert werden und die Veranstaltung hat durchaus das Potential 3.000 Menschen in ihre LAN-Area zu ziehen. Ein Communitymanager, der zugleich den Support im eigenen Forum und eine aufgeräumte Website lösen die Probleme im Voraus. Während der LAN können mit Gameserverhostern Sponsoringverträge abgeschlossen werden um Gameserver verschiedener Art bereitzustellen. Auch die Möglichkeit Gastserver mitzubringen würde die Problematik fehlender Gameserver etwas mildern und die Spielediversität fördern. Die LAN-Area sollte von Event- und anderen Bühnen getrennt werden. Weiter würden zwei bis drei Gamer im Orgateam restliche Probleme aufdecken können.
Wenn einige der oben genannten Probleme beseitigt werden, ist der Preis für die Veranstaltung gerechtfertigt, so wie es in diesem Jahr lief, definitiv nicht!
Ob wir zu der nächsten Dreamhack (DHDE17 – 13.01. – 15.01.2017) fahren ist bisher nicht entschieden – nach Meinungen in der Discordapp geht es vielen anderen auch so.

Sollten Fragen oder Anmerkungen zu meiner Bewertung entstehen dürft ihr euch gerne bei mir melden, ansonsten vielen Dank für das Lesen dieses langen Artikels.

Java 7 – try mit AutoClosables, try(Ressource res), Type Inference

Die erste Frage, die ich mir heute morgen gestellt habe, wie komme ich drauf, dass ich Ende 2015 Beiträge über Java 7 veröffentliche…naja ich komme jetzt gerade erst dazu, mich damit zu beschäftigen, leider…

AutoCloseable – ein Interface, das mit Java 7 eingeführt wurde, es fordert die Implementierung einer Methode … schrecklich überraschend … close() … ein. Zudem kann ich nun Ressourcen im Kopf des try-Blocks deklarieren, der Vorteil hier ganz klar; Egal, ob die try-Anweisung vollständig abläuft oder abrupt  endet, die close()-Methode von Ressourcen, die das Interface AutoClosable implementieren werden definitiv aufgerufen. So können Socket, Filehandles oder Reader-Ressourcen automatisch beendet werden, auch dann wenn eine Exception auftritt. Es können zudem mehrere Ressource ; separiert im try instanziiert werden, bspw.:

Hingewiesen sei auf das rot-markierte Semikolon nach der zweiten Ressourcen, dieses ist optional und kann ja nach Belieben gesetzt oder nicht gesetzt werden. Ein weiterer Vorteil ist, dass zur Laufzeit bekannt ist, welche Ressourcen bereits geschlossen worden sind. Das bedeutet, tritt ein Problem bei der Instanziierung von r2 auf, so wird nur r1 automatisch geschlossen, da dies für r2 nicht notwendig ist.

Aber in dem kurzen Codeblock ist noch mehr, das so nicht ganz so einfach mit Java 6 ging. Genau…die Exceptions…ein Pipe-Symbol/logisches ODER…Das ganze nennt sich Exception-Chaining. Wenn wie in diesem Beispiel drei Exceptions die gleiche Art der Behandlung haben, können die Blöcke auf o.g. Weise zusammengefasst werden…auch wieder sehr praktisch.

Zu guter letzt möchte ich noch weiter auf die Optimierungen beim Entwickeln eingehen. Seit Java 7 können in Variablendeklarationen von Generics die typisierenden Argumente beim Konstruktor-Aufruf weggelassen werden, also statt:

Können wir die verkürzte Schreibweise verwenden:

Die Kombination aus den beiden spitzen Klammern ‚<>‘ wird auch als Diamond bezeichnet. Zusammengefasst kann der Diamond den parametrisierten Typ des Konstruktors einer generischen Klasse ersetzen. Das Weglassen des Diamonds ist bei der Instanziierung nicht erlaubt, weil sonst (in diesem Fall) der Raw-Type der Hashmap angenommen und nicht der generische Typ angenommen wird.

Empfohlen wird zudem der Einsatz ausschließlich bei der Instanziierung von Variablen, nicht in Funktionsaufrufen, auch wenn dies theoretisch möglich ist.

Java7 – Neuerung – Danke!

Heute … gestern … und auch der Tag davor – so fühlt es sich zumindest als Java-Entwickler oftmals an, wenn man mal wieder in die Situation kommt, equals() und hashCode()-Methoden in einem Objekt zu implementieren.  So führt der traditionelle Weg am Referenzvergleich, null-Check und am Ende an diversen if() ..elseif()-Checks vorbei. Diese als „verbose“ (langatmige) Implementierung kennt jeder. Etwas schicker geht es mit den ternären Operatoren (zur Erinnerung: ‚wenn ? dann : sonst‘). Obi Ezechukwu hat uns dann mit seinem compactEquals weitergeholfen, als er seine compactEquals()-Methode vorgestellt hat; er fügt die zu vergleichenden Members der zu vergleichenden Objekte einem Array hinzu,  und nutzt Arrays.equals(Object,Object). Ein ähnlich umständliches Verfahren wird bekannterweise auch für der Überschreiben der hashCode()-Methode eingegangen, was ja notwendig ist, wenn die equals()-Methode eines Objekts überschrieben wird.

IDEs wie IntelliJ, Netbeans und Eclipse helfen natürlich bei der automatischen Erstellung der Methoden in altertümlichem Sinne, was den Stil allerdings auch nicht schöner macht.

Mit der Einführung von Java7, können equals() und hashCode() nun recht komfortabel, objektweise erstellt werden.

 

 

Hingewiesen sei hier auch noch auf die deepEquals()-Methode der Objects-Klasse.

 

Quellen: http://docs.oracle.com/javase/7/docs/api/java/util/Objects.html

Kabelanschluss…Bildstörungen

Wir haben einen Kabelanschluss von Kabel Deutschland. Der Empfang ist allerdings lange Zeit eher schlecht gewesen, was im Detail bedeutet, dass neben Fragmentbildungen und kompletten Bildausfällen über mehrere Sekunden auch Tonstörungen nach sich zog.

Ich habe mich mit Kabel Deutschland in Verbindung gesetzt, damit Fernsehen, wieder Fernsehen ist und nicht ein reines Ärgernis. Nach drei Telefonaten mit eher inkompetenten Mitarbeitern an der Hotline habe ich mir gedacht, gibst du den Vorschlägen von den Damen und Herren einfach mal nach und ziehst ein neues Kabel vom Hausanschluss bis zum Endgerät. Das natürlich ohne Erfolg, da das Kabel tadellos war.

Nach weiteren Telefonaten wurde mir angeboten, dass ein Techniker der Kabel Deutschland mit einem horrenden Stundensatz das Problem sicherlich lösen könnte, was ich dankend ablehnte…es kann ja nicht sein, dass ich mir die Blöße gebe, es nicht selbst herausfinden zu können. Elektrotechnik und Digitaltechnik im Studium sollten ja eigentlich als Grundlage ausreichen. Mein Vater seines Zeichens Elekroinstallateur bekam dies mit und nannte mir die einfache Lösung:

Hausanschluss öffnen (eine Plombe gab es scheinbar nie), das Kabel auf der Hausseite neu verkabeln, wichtig dabei ist, dass man sich ein Stück Sandpapier nimmt und die außen um das Kabel liegende Schirmung und die anschlussseitige Klemme wieder „kontaktfreudig“ macht. Das Problem besteht in so einem Fall häufig in einer korrodierten Masseklemme in der Hausanschlussdose.

Apache Wicket – Der Einstieg

Seit nun fast 15 Monaten beschäftige ich mich in meinem Projektumfeld mit Spring und Hibernate. Langsam meldet sich mit Innerstes und schreit nach mehr Input. Andere lernen Sprachen oder versuchen neue Kunststückchen mit ihren Fingern zu vollführen, aber der allgemeine Informatiker…nunja…macht das nicht.

Der Informatiker erweitert sein Repertoire um Technologien und Erfahrungen. Ich habe mir nun Apache Wicket vorgenommen. Bei Wicket kommt mit Wissen zu Java und HTML vollkommen aus. Ich werde versuchen, einige der wichtigsten Fragestellungen, die beim Einarbeiten in dieses Framework auftreten, nieder zu schreiben und natürlich auch zu beantworten.

Nachdem wir das Warum? geklärt haben, kommen wir zu einem schweren Schritt, wie anfangen? O_o

  1. Apache Tomcat 7 mit JDK 7 (bspw. OpenJDK 7) sollte als Grundlage vorhanden sein
  2. Eine brauchbare IDE: https://www.jetbrains.com/idea/ – die meiner Meinung nach beste IDE (Netbeans und Eclipse wurden abgelöst)
  3. Ich empfehle die Verwendung von Maven als Dependency Manager

Okay, sobald wir das alles eingerichtet haben…sind schon gut und gerne mal 60 Minuten vergangen ;-).

Das war die Einrichtung der Entwicklungsumgebung, kommen wir nun zum ersten lauffähigen Projekt mit Wicket. Aber was nun? Na gut, keine Ahnung, besorgen wir uns Hilfe bei Leuten die Apache Wicket entwickeln und uns grandiose Hilfen anbieten. Maven Archtypes…Neues Projekt –> Maven –> **gnampf** Wicket in Version 1.3.2 als Archtype vorhanden…Version 7 ist doch aktuell….gerade gelesen :-/ na gut wicket.apache.org *such* Quickstart –> Boah fett *.*

Hier gibt es einen generierten Befehl, mit dessen Hilfe wir ein Wicketprojekt erstellen können:

Ich habe mal die interessanten Parameter des Befehls in rot markiert, diese können bspw. in IDEA als neuer Archtype angegeben und gespeichert werden. Sobald das Projekt erfolgreich erstellt worden ist, haben wir eine lauffähige WebApplicationentwickelt …. *yey*

Aber was genau ist hier nun passiert? Mit dem MavenArchtype wurde eine POM erzeugt, diese lädt alle Dinge automatisch aus dem angegebenen Repository herunter, wenn dort nicht verfügbar, ggf. auch von anderer Stelle (Dependency Management). Zusätzlich können in der POM Informationen zur Applikation hinterlegt werden, wie Author, Applikationsname oder Verison eurer Applikation. Die Version kann bspw. bei Verwendung von Releasezyklen automatisiert durch einen Jenkins verwaltet werden….doch dazu später mehr….vielleicht ;-).

Also was jetzt? Genau, ein Container in dem die Webapplikation (WebApp) laufen kann, muss her. Oben in den Bedingungen schon gesehen…Tomcat 7.  In der Pom ist auch ein alternativer Servelet-Container als Dependency vorhanden, der natürlich auch problemlos verwendet werden kann:

Es ist wichtig, dass Java 7 verwendet wird, wie es hier auch steht:

 

 

Nach Konfiguration des Tomcat 7 in der IDE sollte einem Start der Applikation nichts mehr im Wege stehen. Bereits nach 453ms öffnet such ein Browserfenster und die „Quickstart“ erscheint.

Glück auf! Später mehr 😉

Spotify unter Debian Wheezy

Ich benutze Spotify Premium, weil ich es leid war, auf umständlichen Wegen immer wieder meine Playlists zu sortieren oder mich um die Erweiterung dieser zu kümmern.  Aber nun genug von der Werbeveranstaltung, ich will ich kurz erzählen, wie man mit Aptitude Spotify ganz einfach installieren kann:

  1. sudo apt-add-repository -y „deb http://repository.spotify.com stable non-free“
    So wird das Spotify repository als Paketquelle hinzugefügt.
  2. sudo apt-key adv –keyserver keyserver.ubuntu.com –recv-keys 94558F59
    So wird der Public Key zur Verifizierung der Korrektheit hinzugefügt.
  3. sudo apt-get update
    Interne Versionslisten aktualisieren.
  4. sudo apt-get install spotify-client
    Fehlermeldung! Der Grund hierfür beruht darauf, dass Spotify gegen eine feste Version von libssl entwickelt wird, nämlich libssl0.98. Diese ist aber seit Release von Version 1.0 nicht mehr verfügbar und deswegen  müssen wir diese Version von Hand installieren:

    1. uname -a
      Ermittlung der verwendeten Architektur des Linux
    2. Download des Paketes aus den offiziellen Debianpaketquellen.
      Hinweis:
      i386 und i686 -> 32Bit
      amd64 –> 64Bit
    3. sudo dpkg –install libssl0.9.8_0.9.8o-4squeeze14_i386.deb
      oder mit Rechtsklick und dem GDebi-Paket-Installer das Paket installieren
  5. sudo apt-get install spotify-client
    Nun kann der Spotify-Client problemlos installiert werden.