From 2ce49eff15b2b9dd69f20f942d88061fa307339b Mon Sep 17 00:00:00 2001 From: 3009594 Date: Fri, 30 Aug 2024 23:15:41 +0200 Subject: [PATCH] Streams --- .../SortierAlgorithmus/MergeSort.java | 2 +- .../SortierAlgorithmus/QuickSort.java | 67 +++++++++++++++++++ .../ExceptionHandling/ExceptionHandling.java | 2 +- .../src/oop/ExceptionHandling/Finally.java | 3 +- Programmierung2/src/streams/Beispiele.java | 42 ++++++++++++ Programmierung2/src/streams/Beispiele2.java | 23 +++++++ Programmierung2/src/streams/Streams.java | 44 ++++++++++++ 7 files changed, 180 insertions(+), 3 deletions(-) create mode 100644 Programmierung2/src/Algorithmus/SortierAlgorithmus/QuickSort.java create mode 100644 Programmierung2/src/streams/Beispiele.java create mode 100644 Programmierung2/src/streams/Beispiele2.java create mode 100644 Programmierung2/src/streams/Streams.java diff --git a/Programmierung2/src/Algorithmus/SortierAlgorithmus/MergeSort.java b/Programmierung2/src/Algorithmus/SortierAlgorithmus/MergeSort.java index 54da234..26decb0 100644 --- a/Programmierung2/src/Algorithmus/SortierAlgorithmus/MergeSort.java +++ b/Programmierung2/src/Algorithmus/SortierAlgorithmus/MergeSort.java @@ -2,7 +2,7 @@ package Algorithmus.SortierAlgorithmus; public class MergeSort { /* - Zeitkomplexität von O(n log n) - * - Raumkomplexität O(n) + * - Raumkomplexität(Space) O(n) * - prinzip Divide (Teilen) und Conquer (Zusammenfügen) * Divide (Teilen): Das Array wird rekursiv in zwei Hälften geteilt, bis jede Teilmenge nur noch ein einziges Element enthält. * Conquer (Zusammenfügen): Die kleineren Teilmengen werden dann wieder zusammengeführt und dabei sortiert, um schließlich das vollständig sortierte Array zu erhalten. diff --git a/Programmierung2/src/Algorithmus/SortierAlgorithmus/QuickSort.java b/Programmierung2/src/Algorithmus/SortierAlgorithmus/QuickSort.java new file mode 100644 index 0000000..5c66b5a --- /dev/null +++ b/Programmierung2/src/Algorithmus/SortierAlgorithmus/QuickSort.java @@ -0,0 +1,67 @@ +package Algorithmus.SortierAlgorithmus; + +public class QuickSort { + /* - Zeitkomplexität von O(n log n) im Durchschnitt und O(n^2) im schlechtesten Fall + * - Raumkomplexität (Space) O(log n) für den Aufrufstack bei der rekursiven Implementierung + * - Prinzip: Divide (Teilen) und Conquer (Erobern) + * Divide (Teilen): Wähle ein Pivot-Element und teile das Array in zwei Teile: + * - Elemente kleiner als das Pivot auf der linken Seite, + * - Elemente größer als das Pivot auf der rechten Seite. + * Conquer (Erobern): Wende Quick Sort rekursiv auf die beiden Teilarrays an. + * - Keine explizite Merge-Phase: Im Gegensatz zu Merge Sort führt Quick Sort das Sortieren während des Teilens durch, daher gibt es keine separate Zusammenführungsphase. + */ + + public static void main(String[] args) { + int arr[] = {12, 11, 13, 5, 6, 7}; // Initialisiere ein Array mit unsortierten Werten + quickSort(arr, 0, arr.length - 1); // Rufe Quick Sort auf dem gesamten Array auf + + // Ausgabe des sortierten Arrays + System.out.println("Sortiertes Array:"); + for (int i : arr) + System.out.print(i + " "); + } + + // Quick Sort Methode + public static void quickSort(int arr[], int anfang, int end) { + if (anfang < end) { // Bedingung zur Fortsetzung der Rekursion, solange das Teilarray mehr als ein Element enthält + int pivo = partition(arr, anfang, end); // Finde das Pivot-Element und teile das Array + quickSort(arr, anfang, pivo - 1); // Sortiere das linke Teilarray + quickSort(arr, pivo + 1, end); // Sortiere das rechte Teilarray + } + } + + // Partitionierungsfunktion, die das Array um das Pivot-Element herum aufteilt + static int partition(int arr[], int anfang, int end) { + int pivo = anfang; // Wähle das erste Element als Pivot + while (true) { // Endlosschleife, die durch 'break' unterbrochen wird + // Finde die Position von 'end' für den ersten Wert, der kleiner ist als das Pivot + while (arr[pivo] <= arr[end] && pivo != end) + end--; // Bewege den 'end'-Zeiger nach links + + if (pivo == end) // Wenn 'pivo' und 'end' gleich sind, ist die Partitionierung abgeschlossen + break; + else if (arr[pivo] > arr[end]) { // Wenn das Pivot größer ist, tausche die Werte + int temp = arr[end]; // Tausche den Wert von arr[pivo] mit arr[end] + arr[end] = arr[pivo]; + arr[pivo] = temp; + pivo = end; // Setze 'pivo' auf die neue Position + } + + // Finde die Position von 'anfang' für den ersten Wert, der größer ist als das Pivot + while (arr[pivo] >= arr[anfang] && pivo != anfang) + anfang++; // Bewege den 'anfang'-Zeiger nach rechts + + if (pivo == anfang) // Wenn 'pivo' und 'anfang' gleich sind, ist die Partitionierung abgeschlossen + break; + else if (arr[pivo] < arr[anfang]) { // Wenn das Pivot kleiner ist, tausche die Werte + int temp = arr[anfang]; // Tausche den Wert von arr[pivo] mit arr[anfang] + arr[anfang] = arr[pivo]; + arr[pivo] = temp; + pivo = anfang; // Setze 'pivo' auf die neue Position + } + } + + return pivo; // Gib die neue Position des Pivot-Elements zurück + } + +} diff --git a/Programmierung2/src/oop/ExceptionHandling/ExceptionHandling.java b/Programmierung2/src/oop/ExceptionHandling/ExceptionHandling.java index 47be6b6..720ce52 100644 --- a/Programmierung2/src/oop/ExceptionHandling/ExceptionHandling.java +++ b/Programmierung2/src/oop/ExceptionHandling/ExceptionHandling.java @@ -72,7 +72,7 @@ public class ExceptionHandling { //also Objekt ist leer! try { int[] arr = null; - System.out.println(arr[4]); + //System.out.println(arr[4]); fehler }catch(Exception e) { System.out.println(e.toString()); diff --git a/Programmierung2/src/oop/ExceptionHandling/Finally.java b/Programmierung2/src/oop/ExceptionHandling/Finally.java index 5269b16..cbd7525 100644 --- a/Programmierung2/src/oop/ExceptionHandling/Finally.java +++ b/Programmierung2/src/oop/ExceptionHandling/Finally.java @@ -52,7 +52,8 @@ public class Finally { return 2; }finally { - return 3; + System.out.println("tu etwas"); } + return x; } } diff --git a/Programmierung2/src/streams/Beispiele.java b/Programmierung2/src/streams/Beispiele.java new file mode 100644 index 0000000..2839638 --- /dev/null +++ b/Programmierung2/src/streams/Beispiele.java @@ -0,0 +1,42 @@ +package streams; +import java.util.Arrays; +import java.util.stream.*; + +public class Beispiele { + + + public static void main(String[] args) { + Integer[] myArray = new Integer[]{10,20,22,30,50}; + Stream myStream = Arrays.stream(myArray); + /* + * Hier macht der Stream nichts, weil die Intermediate-Operation filter + * keine Aktion auslöst, solange keine Terminal-Operation aufgerufen wird. + */ + myStream.filter(i -> (i % 2 == 0));//Keine Wirkung, da keine Terminal-Operation folgt + + + /* + * Hier wird eine Intermediate-Operation (filter) auf dem Stream aufgerufen, + * die die geraden Zahlen aus dem Stream herausfiltert. + * Danach wird die Terminal-Operation count() aufgerufen, die die Anzahl der + * gefilterten Elemente zählt und als long zurückgibt. + */ + long x = myStream.filter(i -> (i % 2 == 0)).count(); // count gibt Long zurück + System.out.println(x); + + // Wiederverwendung von myStream liefert einen Compiler-Fehler, da der Stream bereits abgeschlossen ist. + // Ein Stream kann nur einmal verwendet werden, und nach einer Terminal-Operation wie count() + // ist der Stream geschlossen und nicht wiederverwendbar. + x = myStream.filter(i -> (i % 2 == 1)).count(); // Compiler-Fehler + System.out.println(x); + + // Compiler-Fehler: Stream has already been operated upon or closed + // Dieser Fehler tritt auf, weil myStream nach der ersten count()-Operation nicht erneut verwendet werden kann. + long y = myStream.filter(i -> (i % 2 == 1)).count(); // Compiler-Fehler + System.out.println(y); + + } + + + +} diff --git a/Programmierung2/src/streams/Beispiele2.java b/Programmierung2/src/streams/Beispiele2.java new file mode 100644 index 0000000..4431b68 --- /dev/null +++ b/Programmierung2/src/streams/Beispiele2.java @@ -0,0 +1,23 @@ +package streams; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Stream; + +public class Beispiele2 { + + public static void main(String[] args) { + + Integer[] myArray = new Integer[]{10,20,22,30,50}; + Stream myStream = Arrays.stream(myArray); + // entweder + myStream.sorted().forEach(System.out::println);; + + //oder + myStream.forEach(i -> System.out.println(i)); + + + + + } +} diff --git a/Programmierung2/src/streams/Streams.java b/Programmierung2/src/streams/Streams.java new file mode 100644 index 0000000..17be61a --- /dev/null +++ b/Programmierung2/src/streams/Streams.java @@ -0,0 +1,44 @@ +package streams; + +/* Was ist das? + * - Arbeitet mit einer Vielzahl von Datenquellen + * . Collections (List, Set, Map, etc.) + * . Arrays + * . Stream von Dateien (File IO) + * . ArrayList, LinkedList, etc. + * + * - keine Notwendigkeit von loops + * - Kein Speichern: Streams speichern keine Daten, sondern leiten sie von einer Quelle ab. + * - Lazy Evaluation: Operationen werden erst ausgeführt, wenn eine Terminal-Operation aufgerufen wird. + * - Einmalige Verwendung: Ein Stream kann nur einmal verwendet werden. + * . Alternative Möglickeit eine andere Stream für das Selbe List ertsellen + * Sobald ein Stream verarbeitet wurde, kann er nicht erneut verwendet werden. + * - Streams können grundsätzlich überall in einer Java-Klasse verwendet werden + * , einschließlich in Methoden, Konstruktoren und anderen Bereichen, solange die Datenquelle und + * die notwendigen Imports vorhanden sind. + * + * . Stream-Operationen: (Siehe Bild) + * 1. Intermediate (Zwischenoperationen) + * - transformieren einen Stream in einen anderen Stream. + * - sie werden erst ausgeführt, wenn eine Terminal-Operation aufgerufen wird. + * + * 2. Terminal-Operationen (Siehe Bild) + * - schließen den Stream ab und liefern ein Ergebnis oder eine Nebenwirkung. + * + * Hinweis: + * - Streams in Java arbeiten hauptsächlich mit (Objekten) und nicht direkt mit (primitiven) Datentypen + * - für (primitiven) Datentypen : + * . IntStream für int + * . LongStream für long + * . DoubleStream für double + * + */ + + +public class Streams { + + public static void main(String[] args) { + + } + +}