W4DSKI-105

Fortgeschrittene Programmierung

Version: 29. April 2025

Dozent: Mario Pfob

## Organisatorisches
## Projektbericht - Findet ein Problem (im Unternehmen) - (er)findet dazu Daten - Keine doppelten Themen oder Gruppen
## Projektbericht - Problembeschreibung (PDF) - Tabelle mit **mind.** 20 Rows (TXT oder CSV) - Code (Java) - **Alles** hochladen in Moodle (als ZIP) (Vor- & Nachname im Dateinamen)

Projektbericht

Konkrete Aufgabenstellungen in Moodle

## Programmentwurf am PC - **Anzahl Punkte:** 50 - **Termin:** 16.06.2025 - **Dauer:** 60 Minuten Übungsstunde am 28. Mai im PC-Raum
## Wiederholungsklausur 🚨 Programmentwurf am PC 🚨 - **Anzahl Punkte:** 100 - **Termin:** 17.04.2025 - **Dauer:** 85 Minuten
## Folien Verwendung entweder ... - Web: https://prj-w4dski-105-prd.web.app/ - PDF: https://prj-w4dski-105-prd.web.app/?print-pdf ([Doku](https://revealjs.com/pdf-export/))
## Einleitung

Performance | Wartung | Pragmatismus

Datums & Zeit

                
                
System

                
                
## Java 24 - Neuerungen https://blog.jetbrains.com/idea/2025/03/java-24-and-intellij-idea
Nachtrag 'guarded pattern case labels'

                
                
JEP 441
## 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


                
                
## Optional
Beispiel

                
                

Übung Optional


                
                
## IO-Operationen
## JavaFX
module-info.java

                    module de.app {

                        requires javafx.controls;
                        requires javafx.fxml;

                        opens medicine to javafx.fxml;

                        exports medicine;

                    }
                
Kleines Beispiel

                package medicine;

                import javafx.application.Application;
                import javafx.scene.Scene;
                import javafx.scene.control.Label;
                import javafx.scene.layout.StackPane;
                import javafx.stage.Stage;

                public class JavaFXExample extends Application {

                    @Override
                    public void start(Stage stage) {
                        String javaVersion = System.getProperty("java.version");
                        String javafxVersion = System.getProperty("javafx.version");
                        Label l = new Label("A medicine app running with JavaFX " + javafxVersion + " and JDK " + javaVersion + ".");
                        Scene scene = new Scene(new StackPane(l), 540, 150);
                        stage.setScene(scene);
                        stage.show();
                    }

                    public static void main(String[] args) {
                        Application.launch();
                    }

                }
                
Medicine App

                package medicine;

                import javafx.application.Application;
                import javafx.fxml.FXMLLoader;
                import javafx.scene.Parent;
                import javafx.scene.Scene;
                import javafx.stage.Stage;

                import java.io.IOException;

                public class MedicineApp extends Application {

                    @Override
                    public void start(Stage stage) throws IOException {
                        FXMLLoader loader = new FXMLLoader(getClass().getResource("MedicineGUI.fxml"));
                        Parent root = loader.load();
                        Scene scene = new Scene(root);
                        stage.setScene(scene);
                        stage.show();
                    }

                    public static void main(String[] args) {
                        Application.launch();
                    }

                }
                
Medicine Controller

                package medicine;

                import javafx.fxml.FXML;
                import javafx.scene.control.TextField;

                public class MedicineController {

                    @FXML
                    private TextField txtName; // same name as in the FXML file!
                    @FXML
                    private TextField txtAge; // same name as in the FXML file!

                    public void initialize() {
                        // Initialization logic if needed
                    }

                    public void registerPatient() {
                        String patientName = txtName.getText();
                        String patientAge = txtAge.getText();

                        System.out.println("Patient Name: " + patientName);
                        System.out.println("Patient Age: " + patientAge);
                    }

                }
                
MedicineGUI.fxml

                    
                
## JavaFX Übungen Siehe Skript
## 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](https://docs.oracle.com/en/java/javase/24/docs/api/java.base/java/io/PrintWriter.html)
## 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

                
## Übung Queue Erstellen ein Programm, das eine History-Funktion für Befehle (String) implementiert. - Nutze `ArrayDeque`, um die letzten 10 Befehle zu speichern. - Ältere Befehle sollen automatisch entfernt werden, wenn die Kapazität überschritten wird. - Implementiere `showHistory()`, welche die Befehle in zuletzt eingetippter Reihenfolge anzeigt.
## 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

## 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](https://bwinf.de/fileadmin/wettbewerbe/bundeswettbewerb/34/1_runde/34_Aufgaben.pdf)
## 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

                
## Ü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.
## Exkurs - Information Retrieval - Elastic(search) (nicht im Skript)

Suche kann komplex werden 😵‍💫

Demo

## 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.

## Funktionale Programmierung
Double Colon

                
## Lambda-Expressions
Function

                
Predicate

                
Supplier

                
Consumer

                

Übung Lambda-Expressions

Erstellen 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

                
## Exkurs - Stream Gatherers (nicht im Skript)
Fixed Windows

                
Sliding Windows

                
Folding

                
Scanning

                

Ü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
## Advanced String Operations and Manipulation
## StringBuilder and -Buffer
String vs. StringBuilder

                
StringBuilder

                

Übung StringBuilder

Entwickel eine ProductCatalogBuilder-Klasse, die einen dynamischen Produktkatalog für einen Online-Shop erstellt. Die Klasse soll:

  • Einen StringBuilder mit optimierter initialer Kapazität verwenden
  • Produkte mit Name, Beschreibung, Preis und Kategorie in strukturiertem HTML-Format ausgeben
  • Eine Methode addProduct(Product product) anbieten, die ein Produkt zum Katalog hinzufügt
  • Eine Methode generateCatalogByCategorySection() implementieren, die Produkte nach Kategorien gruppiert
  • Eine Methode applyPriceFilter(double minPrice, double maxPrice) bereitstellen, die den Katalog nach Preisbereich filtert
## Regex und Pattern Matching
find()

                
                
matches()

                
                
group()

                
                
results()

                
                
splitWithDelimiters()

                
                

Übung Regex

Implementiere einen Passwort-Validator für ein Login-System, der mit regulären Ausdrücken prüft, ob ein Passwort die Sicherheitsanforderungen erfüllt (mindestens 8 Zeichen, Groß- und Kleinbuchstaben, Zahlen und Sonderzeichen).

## Ausblick
## AI DeepLearning4J, Spring AI, LangChain4J, MCP, ...

LLM-Beispiel

Concerto for Java & AI

Java 25

JEP-Übersicht
Java Duke