W4DSKI-105 · Fortgeschrittene Programmierung
Dozent: Pfob, Mario
Java Duke

Organisatorisches

Programmentwurf am PC

  • Anzahl Punkte: 50
  • Termin: 15.05.2025
  • Dauer: 60 Minuten

Wiederholungsprüfung

Termin: 24.04.2025

  • Kurztest
    • Anzahl Punkte: 20
    • Start: 09:00 Uhr
    • Dauer: 25 Minuten
  • Programmentwurf
    • Anzahl Punkte: 80
    • Start: 09:45 Uhr
    • Dauer: 60 Minuten

Einleitung

Performance | Wartung | Pragmatismus

Datums & Zeit

                
                
System

                
                

Warum dieses Semester relevant sein könnte …

Vorher

dhbw-data-structures-before

Nachher

dhbw-data-structures-after

Einführung fortgeschrittene Objektorientierung

Packages

Unterscheidung zwischen:

  • User-defined Packages
  • Built-in Packages

User-defined Packages


                └── root
                  └── de
                    └── dhbw
                        └── ravensburg
                            └── icu4j
                                └── Patient.java
                

User-defined Packages


                package de.dhbw.ravensburg.icu4j;

                class Patient {

                    private String name;
                    private int age;

                    Patient(String name, int age) {
                        this.name = name;
                        this.age = age;
                    }

                    String getName() {
                        return name;
                    }

                    int getAge() {
                        return age;
                    }
                }
                

Built-In Packages


                import java.util.Scanner;

                class ScannerExample {

                    public static void main(String[] args) {
                        Scanner scanner = new Scanner(System.in);

                        System.out.print("Enter your name: ");
                        String name = scanner.nextLine();

                        System.out.println("Hello, " + name + "!");

                        scanner.close();
                    }

                }
                

Fully Qualified Names


                class ScannerExampleQualified {

                    public static void main(String[] args) {
                        java.util.Scanner scanner = new java.util.Scanner(System.in);

                        System.out.print("Enter your name: ");
                        String name = scanner.nextLine();

                        System.out.println("Hello, " + name + "!");

                        scanner.close();
                    }

                }
                

Wildcard Import


                import java.math.*;

                public class MathWildcard {

                    public static void main(String[] args) {
                        BigInteger a = new BigInteger("1");
                        BigDecimal b = new BigDecimal("2");
                        System.out.println("Number: " + a);
                        System.out.println("Number: " + b);
                    }

                }
                

Static Import


                import static java.lang.Math.PI;

                public class MathStatic {

                    public static void main(String[] args) {
                        System.out.println("PI: " + PI);
                    }

                }
                

Übung Packages

  1. Erstelle ein Paket namens filmtools.
  2. Definiere eine Klasse FilmUtils in diesem Paket mit einer Methode calculateAverageOfRatings(double[] movieRatings).
  3. Schreibe eine Hauptklasse FilmApp, die diese Methode verwendet. Wo muss diese Klasse gespeichert werden, um ein Import-Statement zu verwenden?

Modules

module-info.java


                module org.mariopfob {}
                

exports Keyword


                module org.mariopfob {
                    exports programming;
                }
                

requires Keyword


                module de.svgruppe {
                    requires org.mariopfob;
                }
                

Verwendung von anderen Modulen


                package newsapp;

                import programming.Feed;

                public class NewsApp {
                    public static void main(String[] args) {
                        Feed feed = new Feed("Example Feed", "https://example.com/feed");
                        System.out.println("Feed Name: " + feed.feedName());
                    }
                }
                

Module Import Declarations

https://openjdk.org/jeps/494

(2nd Preview)

Übung Modules

Siehe Skript

JavaDoc

Single line comment


                    package de.dhbw.ravensburg.icu4j;

                    class HospitalUtils {

                        double calculateBodySurfaceArea(double height, double weight) {
                            // Option 1: BSA in m² is used for drug dosing
                            return Math.sqrt((height * weight) / 3600); // Option 2: BSA in m² is used for drug dosing
                        }

                    }
                

Multiline comment


                    package de.dhbw.ravensburg.icu4j;

                    class MedicamentValidator {

                        boolean validateMedicamentName(String medicamentName) {
                            /*
                             * Examples of valid names:
                             * - "Aspirin"
                             * - "Paracetamol"
                             * - "Ibuprofen"
                             * Examples of invalid names:
                             * - "A" (too short)
                             * - "Paracetamol123" (contains numbers)
                             * - "Ibuprofen!" (contains special characters)
                             * - " " (empty string)
                             */
                            if (medicamentName == null || medicamentName.trim().isEmpty()) {
                                return false; // Invalid name
                            }
                            if (medicamentName.length() < 3 || medicamentName.length() > 50) {
                                return false; // Invalid length
                            }
                            if (!medicamentName.matches("[a-zA-Z\\s]+")) { // Regex: siehe Kapitel 8
                                return false; // Invalid characters
                            }
                            return true;
                        }

                    }
                

Javadoc comment


                    package de.dhbw.ravensburg.icu4j;

                    class IcuMonitor {

                        /**
                         * Counts the number of patients in the ICU who are children (under 18 years old).
                         *
                         * @author Dr. Shaun Murphy
                         * @since 0.0.1
                         * @param patients Array of {@link Patient} to be monitored.
                         * @return The number of children in the ICU.
                         */
                        int countChildrenPatientsInICU(Patient[] patients) {
                            int childCount = 0;
                            for (Patient patient : patients) {
                                if (patient.getAge() < 18) {
                                    childCount++;
                                }
                            }
                            return childCount;
                        }

                    }
                

Markdown Javadoc

https://openjdk.org/jeps/467

Reflection

Patient.java


                package de.dhbw.ravensburg.icu4j;

                class Patient {

                    private String name;
                    private int age;

                    Patient(String name, int age) {
                        this.name = name;
                        this.age = age;
                    }

                    String getName() {
                        return name;
                    }

                    int getAge() {
                        return age;
                    }
                }
                

CancerPatient.java


                package de.dhbw.ravensburg.icu4j;

                class CancerPatient extends Patient {

                    private String cancerType;
                    private String treatment;

                    CancerPatient(String name, int age, String cancerType, String treatment) {
                        super(name, age);
                        this.cancerType = cancerType;
                        this.treatment = treatment;
                    }

                    String getCancerType() {
                        return cancerType;
                    }

                    void setCancerType(String cancerType) {
                        this.cancerType = cancerType;
                    }

                    String getTreatment() {
                        return treatment;
                    }

                    void setTreatment(String treatment) {
                        this.treatment = treatment;
                    }

                }
                

Operating.java


                package de.dhbw.ravensburg.icu4j;

                interface Operating {

                    boolean isPatientStillAlive(int heartRate);

                }
                

InvasiveOperation.java


                package de.dhbw.ravensburg.icu4j;

                class InvasiveOperation implements Operating {

                    @Override
                    public boolean isPatientStillAlive(int heartRate) {
                        return heartRate > 0;
                    }

                }
                

ReflectionExample.java


                
                

Generics

Warum nicht Object verwenden?


                    
                

Generic #1


                    
                

Generic #2


                    
                

Generic Boundary


                
                

Wildcard


                
                

Übung Generics


                
                

Null-Handling

Mehrere Möglichkeiten, u.a.

  • Optional
  • JSpecify

Exceptions

Exception Types

Exception-Hierarchie

Exception Handling

try-catch


                

try-with-resources + finally


                

throws


                

throw new


                

Multiple catch


                

Custom Exception


                

Verwendung der Custom Exception


                

Logging


                

Übung Exception Handling

Implementiere eine PasswordValidator-Klasse, die Passwörter anhand verschiedener Kriterien (Mindestlänge, Sonderzeichen, Zahlen, Groß-/Kleinbuchstaben) überprüft.
Erstelle für jeden Validierungsfall eine spezifische Exception (z.B. TooShortPasswordException, NoSpecialCharacterException) und sammle alle auftretenden Fehler, um sie gebündelt zurückzugeben, anstatt bei dem ersten Fehler abzubrechen.

IO-Operationen

Datei Operationen

Relativ vs. Absolut


                
                

Datei lesen


                
                

Datei erstellen und schreiben


                
                

Dateien löschen


                
                

java.nio.file Files


                
                

Übung Datei Operationen

  1. Schreibe ein Programm, das den Benutzer nach einem Dateinamen und einem Text fragt.
  2. Erstelle eine Datei mit dem angegebenen Namen und Inhalt.
  3. Überprüfe danach, ob die Datei erfolgreich erstellt wurde, und gib jeweils eine Meldung aus.
  4. Wenn die Datei bereits existiert, überschreibe sie nicht, sondern hänge den neuen Text unten an.

File Streams

FileInput- und OutputStream


                
                

Übung File-Streams

Siehe Skript

File Buffering

BufferedReader und BufferedWriter


                
                

Übung File Buffering

Siehe Skript

Honorable Mention

PrintWriter

Serialisierung

Nurse.java


                

NurseHandler.java


                

IO Übersicht (vereinfacht)

Mermaid-Link

Data Structures and Collections

List

ArrayList


                

LinkedList


                

Übung List

Implementiere eine zirkuläre Liste auf Basis einer LinkedList für Strings.

  • Erstelle eine Methode String getNext(), die bei jedem Aufruf das nächste Element zurückgibt.
  • Ist das Ende erreicht, beginne wieder von vorne.
  • Ermögliche es, die Anzahl der Durchläufe zu zählen.

Stack

Stack


                

Übung Stack

Siehe Skript

Queue

record Medicine.java


                

PriorityQueue


                

ArrayDeque


                

Map

HashMap


                

LinkedHashMap


                

Übung Map

Aufgabe 4 aus dem Skript

Tree

TreeMap


                

Übung Tree

Siehe Skript

Set

HashSet


                

Übung Set

Aufgabe 5 im Skript

Iterable und Iterator

Iterator einer Liste


                

Eigene Iterable- und Iterator-Klasse


                

Anwendung der eigenen Collection


                

Übung Iterable und Iterator

Siehe Skript

Comparable and Comparator

Eigene Comparable Klasse


                

Anwendung von Comparable


                

Eigener Comparator


                

Anwendung von Comparator


                

Übung Comparable and Comparator

  • Erstelle eine Version-Klasse, die Softwareversionen wie "2.4.1" repräsentiert.
  • Implementiere Comparable, um Versionen semantisch korrekt zu vergleichen (2.10.0 ist größer als 2.9.0).
  • Beachte Fälle wie "1.0.0", "1.0" und "1".
  • Generell kann davon ausgegangen werden, dass Versionen immer aus drei Stellen bestehen und nur Zahlen enthalten.

Collection Übersicht (vereinfacht)

Mermaid-Link

Vector-Klasse nicht relevant

Funktionale Programmierung

Double Colon


                

Lambda-Expressions

Function


                

Predicate


                

Supplier


                

Consumer


                

Übung Lambda-Expressions

  • Erstelle eine Hauptklasse DrugCompatibility mit einer main-Methode.
  • Implementiere die folgenden funktionalen Komponenten:
    • Ein Predicate mit dem Typ ActiveIngredient, das prüft, ob ein Wirkstoff für einen Patienten mit bestimmten Allergien geeignet ist
    • Ein BiPredicate mit den Typen Patient und Drug, das prüft, ob ein Medikament für einen Patienten basierend auf Alter, Gewicht und Allergien geeignet ist
    • Eine Function mit den Typen Drug und String, die eine Standarddosierungsempfehlung erstellt

Streams

Erzeugung


                

Intermediate and Terminate Operations


                

Collectors


                

Übung Streams

Implementiere ein System zur Analyse von Banküberweisungen mit Stream-Operationen. Erstelle dazu eine Klasse Überweisung mit Attributen für Sender, Empfänger, Betrag und Datum. Entwickle anschließend Stream-Pipelines, die folgende Anforderungen erfüllen:

  • Identifiziere verdächtige Transaktionsmuster durch Filterung aller Überweisungen, deren Betrag knapp unter dem meldepflichtigen Grenzwert (z.B. 10.000€) liegt
  • Gruppiere Überweisungen nach Monaten und berechne die monatliche Gesamtsumme sowie Durchschnittsbetrag pro Transaktion
  • Finde für jeden Kunden die größte ausgehende und eingehende Überweisung unter Verwendung von Collectors.groupingBy() und Collectors.mapping()
  • Implementiere eine Funktion, die mit flatMap() für einen gegebenen Kunden alle direkten und indirekten Zahlungsverbindungen (Überweisungen über maximal einen Zwischenkunden) ermittelt

Algorithmen

Big O Notation

Komplexitätsklassen

Datenstrukturen

Rekursion und Backtracking

Divide and Conquer

Rekursion


                

Backtracking

+ Constraint Propagation

Backtracking

+ Constraint Propagation

Übungen Rekursion und Backtracking

Kassiopeias Weg

Sortieralgorithmen

Vergleich

Algorithmus Zeitkomplexität (Best/Avg/Worst) Speicher Stabil Bemerkungen
Bubble Sort O(n)/O(n²)/O(n²) O(1) Ja Einfach, ineffizient für große Arrays
Selection Sort O(n²)/O(n²)/O(n²) O(1) Nein Einfach, ineffizient für große Arrays
Insertion Sort O(n)/O(n²)/O(n²) O(1) Ja Effizient für kleine Arrays
Quicksort O(n log n)/O(n log n)/O(n²) O(log n) Nein Schnell in der Praxis
Mergesort O(n log n)/O(n log n)/O(n log n) O(n) Ja Garantierte Performance

Bubble Sort


                

Selection Sort


                

Insertion Sort


                

Quick Sort


                

Merge Sort


                

Praxis: Bug bei der Sortierung

tabelle-sortierung-string

Übung Sortieralgorithmen

Entwickel eine Patientenverwaltung für eine Arztpraxis, die Patienten nach Dringlichkeit der Behandlung (Triage-System) und Ankunftszeit sortiert. Stelle sicher, dass der Algorithmus stabil ist.

Suchalgorithmen

Vergleich

Algorithmus Zeitkomplexität Speicherkomplexität Anforderungen Besonderheiten
Lineare Suche O(n) O(1) Keine Einfachste Implementierung
Binäre Suche O(log n) O(1) Sortiert Effizient für große Datenmengen
Interpolation O(log log n) O(1) Sortiert, gleichmäßig verteilt Schnell bei gleichmäßiger Verteilung
Exponential O(log n) O(1) Sortiert Gut für unbegrenzte Arrays
Fibonacci O(log n) O(1) Sortiert Verwendet nur Addition/Subtraktion
Hash-basiert O(1) O(n) Keine Schnellster Zugriff, benötigt Vorverarbeitung

Linear Search


                

Binary Search


                

Interpolation Search


                

Exponential Search


                

Fibonacci Search


                

Hash Search


                

Übung Suchalgorithmen

Entwickle eine Suchfunktion für ein Rezeptverwaltungssystem, das es Nutzern ermöglicht, Rezepte basierend auf verfügbaren Zutaten zu finden. Die Anwendung soll Rezepte zurückgeben, wenn alle angegebenen Zutaten enthalten sind. Implementiere zwei verschiedene Suchstrategien und vergleiche deren Effizienz bei einem Datensatz mit 1000 Rezepten.

Ausblick

AI

DeepLearning4J, Spring AI, LangChain4J, MCP, ...

LLM-Beispiel

Concerto for Java & AI
Java Duke