JUGS Java 8 Hands On Übungen



Ähnliche Dokumente
Programmierkurs Java

Einführung in die Programmierung

Überblick. Lineares Suchen

Java: Vererbung. Teil 3: super()

Erweiterung der Aufgabe. Die Notenberechnung soll nicht nur für einen Schüler, sondern für bis zu 35 Schüler gehen:

Praktikum zu Einführung in die Informatik für LogWiIngs und WiMas Wintersemester 2015/16. Vorbereitende Aufgaben

Studentische Lösung zum Übungsblatt Nr. 7

Informationsblatt Induktionsbeweis

Objektorientierte Programmierung

5. Tutorium zu Programmieren

Mediator 9 - Lernprogramm

WebService in Java SE und EE

Lineargleichungssysteme: Additions-/ Subtraktionsverfahren

Übungen zu Einführung in die Informatik: Programmierung und Software-Entwicklung: Lösungsvorschlag

Einführung in die Java- Programmierung

Zählen von Objekten einer bestimmten Klasse

Programmiervorkurs SS 2011 Technische Universität Darmstadt Jan Hendrik Burdinski, Felix Kerger

5 DATEN Variablen. Variablen können beliebige Werte zugewiesen und im Gegensatz zu

Objektorientierte Programmierung

Verhindert, dass eine Methode überschrieben wird. public final int holekontostand() {...} public final class Girokonto extends Konto {...

Große Übung Praktische Informatik 1

Daten sammeln, darstellen, auswerten

Einführung in die Programmierung

Fachgebiet Informationssysteme Prof. Dr.-Ing. N. Fuhr. Programmierung Prof. Dr.-Ing. Nobert Fuhr. Übungsblatt Nr. 6

C-Probeklausur (Informatik 1; Umfang: C, Teil 1; SS07)

Zahlen auf einen Blick

Java Kurs für Anfänger Einheit 5 Methoden

Einfache Arrays. Annabelle Klarl. Einführung in die Informatik Programmierung und Softwareentwicklung

Zahlenwinkel: Forscherkarte 1. alleine. Zahlenwinkel: Forschertipp 1

Bitte wenden. Name: KURSARBEIT NR. 4 (10 DIFF GA) Seite 1

Übung Grundlagen der Programmierung. Übung 05: Arrays. Abgabetermin: xx.xx.xxxx. Java-Programm Testplan Testergebnisse

Einführung in Java. PING e.v. Weiterbildung Andreas Rossbacher 24. März 2005

1 Vom Problem zum Programm

Das erste Programm soll einen Text zum Bildschirm schicken. Es kann mit jedem beliebigen Texteditor erstellt werden.

Java Kurs für Anfänger Einheit 4 Klassen und Objekte

Die Java Stream API. Funktionale Programmierung mit der Stream API des JDK 1.8. Prof. Dr. Nikolaus Wulff

Auswahlabfragen mit ACCESS

Scala kann auch faul sein

Übungen Programmieren 1 Felix Rohrer. Übungen

Erstellen einer Collage. Zuerst ein leeres Dokument erzeugen, auf dem alle anderen Bilder zusammengefügt werden sollen (über [Datei] > [Neu])

Programmieren in C. Rekursive Funktionen. Prof. Dr. Nikolaus Wulff

Folge 19 - Bäume Binärbäume - Allgemeines. Grundlagen: Ulrich Helmich: Informatik 2 mit BlueJ - Ein Kurs für die Stufe 12

Viele Bilder auf der FA-Homepage

Programmieren in Java

Übungen zur Vorlesung Einführung in die Informatik Wintersemester 2010/11

Software-Engineering und Optimierungsanwendungen in der Thermodynamik

Algorithmen und Datenstrukturen

Kapitel 4 Die Datenbank Kuchenbestellung Seite 1

Kulturelle Evolution 12

Professionelle Seminare im Bereich MS-Office

Der lokale und verteilte Fall

Kontrollstrukturen und Funktionen in C

Übung Grundlagen der Programmierung. Übung 03: Schleifen. Testplan Testergebnisse

Delegatesund Ereignisse

U08 Entwurfsmuster (II)

Institut für Programmierung und Reaktive Systeme 25. August Programmier-Labor Übungsblatt. int binarysearch(int[] a, int x),

Erstellen von x-y-diagrammen in OpenOffice.calc

BERECHNUNG DER FRIST ZUR STELLUNGNAHME DES BETRIEBSRATES BEI KÜNDIGUNG

Unsere Webapplikation erweitern

Primzahlen und RSA-Verschlüsselung

Einführung in die objektorientierte Programmierung mit Java. Klausur am 19. Oktober 2005

[zur Information: die Linse a) heißt Konvex-Linse, die Linse b) heißt Konkav-Linse] Unterscheiden sich auch die Lupen voneinander? In welcher Weise?

Erwin Grüner

1 topologisches Sortieren

Informatik Grundlagen, WS04, Seminar 13

2A Basistechniken: Weitere Aufgaben

Dieses Tutorial gibt eine Übersicht der Form Klassen von Struts, welche Besonderheiten und Unterschiede diese aufweisen.

Arbeiten mit UMLed und Delphi

Anzeige von eingescannten Rechnungen

ZAHLUNGSAVIS. Im Zahlungsprogrammteil automatisch erstellen

Javadoc. Programmiermethodik. Eva Zangerle Universität Innsbruck

Technische Hochschule Georg Agricola WORKSHOP TEIL 3. IKT (Informations- und Kommunikationstechnik) an einer MorseApp erklärt

Mit Papier, Münzen und Streichhölzern rechnen kreative Aufgaben zum Umgang mit Größen. Von Florian Raith, Fürstenzell VORANSICHT

Würfelt man dabei je genau 10 - mal eine 1, 2, 3, 4, 5 und 6, so beträgt die Anzahl. der verschiedenen Reihenfolgen, in denen man dies tun kann, 60!.

Deutsches Rotes Kreuz. Kopfschmerztagebuch von:

Datenbanken Kapitel 2


Tipp III: Leiten Sie eine immer direkt anwendbare Formel her zur Berechnung der sogenannten "bedingten Wahrscheinlichkeit".

Grundlagen der Programmierung Prof. H. Mössenböck. 3. Verzweigungen

Kosten-Leistungsrechnung Rechenweg Optimales Produktionsprogramm

Info zum Zusammenhang von Auflösung und Genauigkeit

Bruchrechnung Wir teilen gerecht auf

Einführung in die C++ Programmierung für Ingenieure

Funktionen Häufig müssen bestimmte Operationen in einem Programm mehrmals ausgeführt werden. Schlechte Lösung: Gute Lösung:

Übungsaufgaben zur Programmiersprache Python

Um die Patientenverwaltung von Sesam zu nutzen, muss man die Patienten natürlich zuerst in die Kartei eintragen.

Downloadfehler in DEHSt-VPSMail. Workaround zum Umgang mit einem Downloadfehler

Die Größe von Flächen vergleichen

Mind Mapping am PC. für Präsentationen, Vorträge, Selbstmanagement. von Isolde Kommer, Helmut Reinke. 1. Auflage. Hanser München 1999

Binäre Bäume. 1. Allgemeines. 2. Funktionsweise. 2.1 Eintragen

Übung 9 - Lösungsvorschlag

Objektorientierte Programmierung. Kapitel 12: Interfaces

Rock-Band. Einleitung. Scratch. In diesem Projekt lernst du, wie du deine eigenen Musikinstrumente programmieren kannst! Activity Checklist

Arbeitsblätter. Sinnvolle Finanzberichte. Seite 19

Das sogenannte Beamen ist auch in EEP möglich ohne das Zusatzprogramm Beamer. Zwar etwas umständlicher aber es funktioniert

Abwesenheitsnotiz im Exchange Server 2010

Blog Camp Onlinekurs

Java Reflection. Meta-Programmierung mit der java.lang.reflection API. Prof. Dr. Nikolaus Wulff

Themen. Web Service - Clients. Kommunikation zw. Web Services

Outlook. sysplus.ch outlook - mail-grundlagen Seite 1/8. Mail-Grundlagen. Posteingang

Transkript:

JUGS Java 8 Hands On Übungen (C) Copyright by Michael Inden, 2015 michael.inden@zuehlke.com Lambdas Aufgabe 1a: Was sind gültige Lambdas? Schaue auf das folgende Interface LongBinaryOperator. public interface LongBinaryOperator long applyaslong(final long left, final long right); Nachfolgend sind einige Lambdas gezeigt. Welche davon sind gültig? Wofür erhält man Fehler beim Kompilieren? final LongBinaryOperator v1 = (long x, Long y) -> return x + y; ; final LongBinaryOperator v2 = (long x, long y) -> return x + y; ; final LongBinaryOperator v3 = (long x, long y) -> x + y; final LongBinaryOperator v4 = (long x, y) -> x + y; final LongBinaryOperator v5 = (x, y) -> x + y; final LongBinaryOperator v6 = x, y -> x + y; Tipp: Überlege ein wenig und prüfe deine Vermutungen dann mithilfe der IDE. Aufgabe 1b: Welche Varianten kompilieren, wenn man das Interface wie folgt abändert: public interface LongBinaryOperator long applyaslong(final long left, final Long right); Aufgabe 2a: Schreibe Functional Interfaces für die folgenden Abbildungen / Aufgaben a) Bilde Objekte von Typ String auf int ab: StringToIntConverter b) Bilde Objekte von Typ String auf String: StringToStringMapper und implementiere diese mit mindestens einem Lambda. 1 von 9

JUGS Java 8 Hands On Übungen michael.inden@zuehlke.com Aufgabe 3a: Gegeben sei folgendes rudimentäres Fragment eines Functional Interfaces als Ergänzung der obigen String-Mapper: @FunctionalInterface public interface Mapper<S, T> // TODO: map S -> T // TODO: mapall List<S> -> List<T> Vervollständige die Implementierung, sodass nachfolgendes Programm kompiliert: public static void main(final String[] args) final List<String> names = Arrays.asList("Tim", "Andi", "Michael"); final Mapper<String, Integer> intmapper = String::length; System.out.println(intMapper.mapAll(names)); final Mapper<String, String> stringmapper = str -> ">> " + str.touppercase() + " << "; final List<String> uppercasenames = stringmapper.mapall(names); System.out.println(uppercaseNames); Tipp: Stelle die mapall()-funktionalität mithilfe einer Defaultmethode bereit. Aufgabe 3b: Welche Alternativen bietet das JDK 8? Schaue ins Package java.util.function. Aufgabe 3c: Was ist von Defaultmethoden in Applikationsklassen zu halten? Welche Vorteile bringen diese, welche Fallstricke sollte man bedenken? Diskutiere mit deinem Nachbarn! 2 von 9

Aufgabe 4a: Was ist bei Lambdas und dort ausgelösten Checked Exceptions zu bedenken? Wie kann man folgendes Runnable so korrigieren, dass es kompiliert? final Runnable runner = () -> System.out.println("Throwing"); throw new IOException(); ; Aufgabe 4b: Realisiere ein Functional Interface als Erweiterung zu Runnable, dass eine Checked Exception in den Typ RuntimeException wandelt. @FunctionalInterface public interface RunnableThatThrows extends Runnable @Override default void run() // TODO public void runthrows() throws Exception; Der Aufruf soll dann wie folgt möglich sein: public class Exercise4_RunnableThatThrowsExample public static void main(string[] args) final RunnableThatThrows runner2 = () -> System.out.println("RunnableThatThrows"); throw new IOException(); ; runner2.run(); Aufgabe 4c: Realisiere ein Functional Interface als Erweiterung zu Comparator, dass eine Checked Exception in den Typ RuntimeException wandelt basierend auf folgenden Zeilen: @FunctionalInterface public interface ComparatorThatThrows<T> extends Comparator<T> public int comparethrows(final T t1, final T t2) throws Exception; 3 von 9

KÜR: Beschäftige dich mit der Frage: Wie kann man mit Lambdas rekursive Aufrufe formulieren? Das geht mit etwas tricksen. Widerlege also die Aussage von Angelika Langer, dass Rekursion in Lambdas nicht möglich ist. 1 Starte mit den folgenden, nicht kompilierfähigen Ausdrücken und bringe diese zum Laufen: UnaryOperator<Integer> myfactorialint = Function<Integer, Long> myfactoriallong = i -> i == 0? 1 : i * myfactorialint.apply(i - 1); i -> i == 0? 1 : i * myfactoriallong.apply(i - 1); Tipp: Versuche es mit einem statischen Attribut oder einem Instanzattribut. Was könnte an dem obigen UnaryOperator problematisch sein? Prüfe deine Lösung mit folgenden Aufrufen: myfactorialint.apply(5) myfactoriallong.apply(5) myfactorialint.apply(20) myfactoriallong.apply(20) myfactorialint.apply(50) myfactoriallong.apply(50) Die Ausgaben sind vermutlich wie folgt: 120 120-2102132736 2432902008176640000 0-3258495067890909184 Man erkennt die Überläufe für den Typ Integer bzw. int. Was gibt es für Lösungsmöglichkeiten? Schaue mal in die Klasse Math. Seit Java 8 findet man dort Abhilfe. 1 Maurice Naftalin schreibt dazu Folgendes: Yes, provided that the recursive call uses a name defined in the enclosing environment of the lambda. This means that recursive definitions can only be made in the context of variable assignment and, in fact given the assignment-before-use rule for local variables only of instance or static variable assignment. So, in the following example, factorial must be declared as an instance or static variable. 4 von 9

Collections Aufgabe 1a: Formuliere die Bedingungen Zahl ist gerade", Zahl ist positiv", Zahl ist Null" und Wert ist null" als Predicate<Integer> und/oder als IntPredicate und prüfe diese mit verschiedenen Eingaben. final Predicate<Integer> iseven = //... TODO... final IntPredicate ispositive = //... TODO... Aufgabe 1b: Formuliere die Bedingung "Wort kürzer als 4 Buchstaben" und prüfe das damit realisierte Predicate<String> isshortword. Aufgabe 1c: Kombiniere die Prädikate wie folgt und prüfe wieder: Zahl ist positiv und Zahl ist gerade (Nutze die Methode and()) Zahl ist positiv und ungerade (Nutze einen Aufruf von negate()) Aufgabe 2: Lösche aus einer Liste von Namen all diejenigen Einträge mit kurzem Namen. Wandle dazu die externe in eine interne Iteration um. Die JDK-7-Implementierung aus dem Listing soll mithilfe von JDK-8-Mitteln einfacher gestaltet werden: private static List<String> removeif_external_iteration() final List<String> names = createnameslist(); final Iterator<String> it = names.iterator(); while (it.hasnext()) final String currentname = it.next(); if (currentname.length() < 4) return names; it.remove(); private static List<String> createnameslist() final List<String> names = new ArrayList<>(); names.add("michael"); names.add("tim"); names.add("flo"); names.add("clemens"); return names; Tipp: Nutze das in Aufgabe 1 erstellte Predicate<String> isshortword und die Methode removeif(predicate<t>) aus dem Interface Collection<E>. 5 von 9

Streams JUGS Java 8 Hands On Übungen michael.inden@zuehlke.com Aufgabe 1: Quadriere alle ungeraden Zahlen von 1 bis 10 und ermittle deren Summe: final int result = IntStream.of(1,2,3,4,5,6,7,8,9,10).filter( ). map( ). reduce(0, ); Tipp: Verwende lokale Hilfsvariablen, um die Verarbeitungsabfolgen besser lesbar zu gestalten. Möglicherweise ist Integer::sum beim Aufruf von reduce() nützlich. Aufgabe 2a: Finde mindesten drei unterschiedliche Arten, die Werte von 1 bis 10 als Stream zu erzeugen und (kommasepariert) auszugeben. Aufgabe 2b: Generiere die Ziffernfolge der natürlichen Zahlen als unendlichen Stream. Starte die Ausgabe bei 11 und begrenze diese auf 10 Elemente. Tipp: Nutze die Methoden skip(), limit(), generate(supplier) und iterate(). Zur Umwandlung eines IntStream in einen Stream<Integer> dient die Methode boxed(). collect() und Collectors.joining() hilft bei der Ausgabe. Aufgabe 2c: Bedenke, dass unendliche Streams problematisch sein können insbesondere beim Einsatz der Methode sorted(). Führe folgende Anweisungen zunächst ohne sorted() und danach mit aus. Schaue was passiert: public class Exercise2_InfiniteStreamSurprises public static void main(string[] args) IntStream.iterate(0, i -> i + 1). boxed(). // sorted(). limit(10). map(e -> "" + e). foreach(system.out::println); 6 von 9

Aufgabe 3: Mitunter muss man eine Statistikauswertung erstellen, die auf einen IntStream operiert, etwa wenn man Minimum, Maximum, Durchschnitt usw. berechnen soll. Mit JDK 7 wird dies aufwendig, aber folgende Möglichkeit mit Stream ist auch nicht optimal: final OptionalInt min = IntStream.of(1,2,3,4,5,6,7,8,9,10).min(); final OptionalInt max = IntStream.of(1,2,3,4,5,6,7,8,9,10).max(); final OptionalDouble average = IntStream.of(1,2,3,4,5,6,7,8,9,10).average(); final long count = IntStream.of(1,2,3,4,5,6,7,8,9,10).count(); final long sum = IntStream.of(1,2,3,4,5,6,7,8,9,10).sum(); Was ist daran unschön? Gibt es eine andere Variante? Schaue dich im IntStream um. Aufgabe 4: Gruppiere den Inhalt eines Streams von Strings nach dem Anfangsbuchstaben, sodass wir folgendes Ergebnis erhalten: A=[Andy], T=[Tim, Tom], M=[Mike, Merten] final Stream<String> inputs = Stream.of("Tim", "Tom", "Andy", "Mike", "Merten"); final Map<Character, List<String>> grouped = inputs. //... TODO... System.out.println(grouped); Tipp: Nutze collect() und die Methode Collectors.groupingBy(). Aufgabe 5a: Erstelle ein Programm, das den Ablauf der Verarbeitungs-Pipeline mithilfe von Konsolenausgaben visualisiert. Ein Startpunkt liefern diese Zeilen: Stream.of("Andi", "Barbara", "Carsten", "Marius", "Micha", "Tim"). map(name -> System.out.println("map: " + name); return name.touppercase(); ). filter(name -> System.out.println("filter: " + name); return name.startswith("m"); ). foreach(name -> System.out.println("forEach: " + name)); Welche Erkenntnisse gewinnst du anhand der Ausgaben? In welcher Reihenfolge sollte man die Operationen ausführen? Tausche einmal die Aufrufe von filter() und map(). Aufgabe 5b: Verbessere das Hineinschauen in den Stream durch Aufruf von peek(consumer). 7 von 9

Date and Time API Aufgabe 1: Berechne die Zeit zwischen heute und deinem Geburtstag bzw. deinem Geburtstag und heute. final LocalDate now = LocalDate.now(); final LocalDate birthday = LocalDate.of(1971, 2, 7); Tipp: Verwende die Klasse LocalDate und die Methode until(). Probiere als Variante auch den Aufruf von Period.between(). Aufgabe 2: Ermittle alle Zeitzonen, die mit "America/L " oder "Europe/S " starten und gib diese sortiert auf der Konsole aus oder befülle damit eine Liste. Tipp: Nutze die Klasse ZoneId sowie deren Methode getavailablezoneids(). Setze Streams und das Filter-Map-Reduce-Framework ein, um die zu den zuvor angegebenen Präfixen passenden Zeitzonen-Ids zu ermitteln. Aufgabe 3a: Welcher Wochentag war der Heiligabend 2013 (24.12.2013)? Was für ein Wochentag war der erste und letzte Tag im Dezember? Starte mit folgenden Programmzeilen: final LocalDate christmaseve = LocalDate.of(2014, 12, 24); System.out.println(DayOfWeek.from(christmasEve)); Aufgabe 3b: Berechne das Datum des ersten und letzten Freitags und Sonntags im März 2014. Starte mit folgendem Sourcecode-Schnipsel: final LocalDate midofmarch = LocalDate.of(2014, 3, 15); final TemporalAdjuster tofirstsunday = TemporalAdjusters.firstInMonth(DayOfWeek.SUNDAY); Tipp: Nutze dabei die Klasse TemporalAdjusters und ihre Hilfsmethoden und die Methode with() aus der Klasse LocalDate. Hinweis: Hier gibt es noch folgende alternative Lösung mit der Methode adjustinto() aus dem Interface TemporalAdjuster. tofirstsunday.adjustinto(midofmarch) Welche Variante ist zu bevorzugen bzw. besser zu verstehen? 8 von 9

Aufgabe 4: Gegeben ist folgender selbstdefinierter TemporalAdjuster, der einen Datumswert auf den Anfang des jeweiligen Quartals setzt: Demnach springt man am 18. August auf den 1. Juli usw. Eine Implementierung für diese Datumsarithmetik findet man im Internet unter http://www.leveluplunch.com/java/examples/first-day-of-quarter-java8-adjuster/. Betrachte den Sourcecode und überlege, was ungünstig an dieser Implementierung ist: 2 public class Exercise04_FirstDayOfQuarterOrig implements TemporalAdjuster @Override public Temporal adjustinto(temporal temporal) int currentquarter = YearMonth.from(temporal). get(isofields.quarter_of_year); if (currentquarter == 1) return LocalDate.from(temporal). with(temporaladjusters.firstdayofyear()); else if (currentquarter == 2) return LocalDate.from(temporal).withMonth(Month.APRIL.getValue()). with(firstdayofmonth()); else if (currentquarter == 3) return LocalDate.from(temporal).withMonth(Month.JULY.getValue()). with(firstdayofmonth()); else return LocalDate.from(temporal).withMonth(Month.OCTOBER.getValue()). with(firstdayofmonth()); Tipp: Was kann man vereinfachen? Entferne Spezialbehandlungen und Inkonsistenzen! Wenn du eine auf Monaten basierende Lösung hast, schaue nochmals in die Aufzählung IsoFields. Dort findet man auch DAY_OF_QUARTER. KÜR: Schreibe eine eigene Realisierung des Interface TemporalAdjuster, die 1. den 2. Samstag oder 3. Freitag usw. ermittelt (parametrierbar) oder 2. den Tag der nächsten Gehaltszahlung ermittelt (25. des Monats, oder Werktag davor, falls der 25. auf ein Wochenende fällt) 2 Leider sieht man auch eine der wenigen kleinen Schwächen im neuen Date and Time API: Die Methode withmonth() arbeitet nicht mit Konstanten vom Typ Month, sondern leider mit int-werten. 9 von 9