Vertiefung der Programmierung

Datenstrukturen
Motivation
Welche Datenstrukturen
kennen wir
schon?
Java Collections
Bild: C. Sahnwaldt
Wichtige Datenstrukturen
List
Map
Set
Diese Datenstrukturen (Collections) sind Schnittstellen, deren Methoden durch konkrete Implementierungen umgesetzt werden müssen, z.B. ArrayList<String>.
List
[E] bezieht sich auf den sog. generischen Typ, d.h. hier können sämtliche Klassen angegeben werden
Exkurs: Hash-Tabellen
Eingabe: "Marian"
{ Hash-Funktion }
Ausgabe: Bucket
| Bucket | Wert |
|---|---|
| 0 | Hans |
| ... | ... |
| 13 | Marian |
Hash-Tabellen können nahezu
genauso schnell auf Elemente zugreifen wie Arrays ➔ O(1)
(reale Laufzeit abhängig von Hash-Funktion)
Set (Mengen)
[E] bezieht sich auf den sog. generischen Typ, d.h. hier können sämtliche Klassen angegeben werden
📦 import java.util.Set;
📦 import java.util.HashSet;
Set (Mengen)
- Sets implementieren mathematisch gesehen Mengen
- Diese Datenstruktur sorgt automatisch dafür, dass keine Duplikate angelegt werden
- Bsp.: {1, 2, 2, 3, 3, 4} → {1, 2, 3, 4}
- Der Zugriff ist sehr schnell
- HashSet: O(1)
- TreeSet sortiert automatisch
Sets sind sehr gut geeignet, wenn man sicherstellen möchte, dass keine Duplikate existieren dürfen.
Set (Wichtige Methoden)
-
boolean add(E element)-
Fügt ein Element hinzu, wenn es noch nicht im Set vorhanden ist
-
Beispiel:
set.add("Max");
-
-
boolean remove(Object o)-
Entfernt ein bestimmtes Element aus dem Set
-
Beispiel:
set.remove("Max");
-
-
boolean contains(Object o)-
Prüft, ob ein bestimmtes Element im Set vorhanden ist.
-
Beispiel:
set.contains("Max");
-
-
int size()-
Liefert die Anzahl der gespeicherten Elemente
-
-
boolean isEmpty()-
Prüft, ob das Set keine Elemente enthält.
-
Set (Beispiel)
import java.util.Set;
import java.util.HashSet;
public class Main {
public static void main(String[] args) {
Set<Integer> numbers = new HashSet<>();
numbers.add(1);
numbers.add(2);
numbers.add(2);
for(Integer elem : numbers) {
System.out.println(elem);
}
}
}Ausgabe:
1
2
⌨️ Set (Beispiel)
Map
-
Map speichert Daten als sog. Schlüssel-Wert-Paare (Key-Value-Pairs)
-
Jeder Schlüssel (Key) ist eindeutig, ein Wert darf mehrfach vorkommen
-
Suche nach einem Wert über den Schlüssel ist sehr schnell
→ O(1) für HashMap -
Verändern der Map:
-
Einträge hinzufügen:
put(K key, V value) -
Einträge lesen:
get(K key) -
Einträge löschen:
remove(K key)
-
Maps eignen sich sehr gut für als universelle "Nachschlagewerke".
Map (Implementierungen)
[K] und [V] beziehen sich auf sog. generische Typen, d.h. hier können sämtliche Klassen angegeben werden.
[K] ist Key (=Schlüssel) und [V] ist Value (=Wert)
📦 import java.util.Map;
📦 import java.util.HashMap;
Map (Beispiel)
import java.util.Map;
import java.util.HashMap;
public class Main {
public static void main(String[] args) {
Map<String, Integer> str2num = new HashMap<>();
// Schlüssel-Werte-Paare einfügen
str2num.put("Eins", 1);
str2num.put("Zweihundertdrei", 203);
// Schlüssel-Werte-Paare ausgeben
System.out.println(str2num.get("Eins"));
}
}Map (Wichtige Methoden)
V put(K key, V value)- Fügt ein Schlüssel-Wert-Paar hinzu oder überschreibt den Wert, wenn der Schlüssel schon existiert.
- Beispiel:
map.put("Max", 20);
V get(Object key)- Gibt den Wert zum angegebenen Schlüssel zurück (oder
null, wenn nicht vorhanden). - Beispiel:
map.get("Max");
- Gibt den Wert zum angegebenen Schlüssel zurück (oder
V remove(Object key)- Entfernt das Eintrag-Paar zum Schlüssel.
- Beispiel:
map.remove("Max");
boolean containsKey(Object key)- Prüft, ob ein bestimmter Schlüssel existiert.
- Beispiel:
map.containsKey("Max");
Map (Wichtige Methoden)
boolean containsValue(Object value)- Prüft, ob ein bestimmter Wert existiert
int size()- Gibt die Anzahl der Einträge zurück
boolean isEmpty()- Prüft, ob die Map leer ist
void clear()- Entfernt alle Einträge.
Set<K> keySet()- Gibt alle Schlüssel als Set zurück.
- Beispiel:
map.keySet();
- Beispiel:
- Gibt alle Schlüssel als Set zurück.
Collection<V> values()- Gibt alle Werte zurück
- Beispiel:
map.values();
- Beispiel:
- Gibt alle Werte zurück
⌨️ Map (Beispiel)
Live
coding
Eigene Klassen als Elemente
Eigene Klassen als Elemente
- Für Java-eigene Klasse (z.B. Double, String, Integer, ...) werden Hash-Codes korrekt bestimmt
→ Werte, auf die Objekte zeigen, werden genutzt
z.B. String s = "VProg"; Double d = 2.;
- Das funktioniert nicht für eigene Klassen.
Warum nicht? → Beispiel
public class Person {
private String name;
private boolean isActive;
public Person(String name, boolean isActive) {
this.name = name;
this.isActive = isActive;
}
}Welcher Wert soll hier als Schlüssel
dienen?
equal- und hashCode-Methoden
import java.util.Set;
import java.util.HashSet;
public class Main {
// Here is the start!
public static void main(String[] args) {
Set<Person> set = new HashSet<>();
set.add(new Person("Marian"));
set.add(new Person("Marian"));
for (Person elem : set) {
System.out.println(elem.getName());
}
}
}
import java.util.Objects;
class Person {
String name;
Person(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
@Override
public boolean equals(Object otherObject) {
String other = ((Person) otherObject).getName();
return this.name.equals(other);
}
@Override
public int hashCode() {
return Objects.hash(this.name);
}
}

📦 import java.util.Objects;
Java Collections (Ausblick)
Bild: C. Sahnwaldt
Zusammenfassung
-
Je nach Anwendungsfall sind unterschiedliche Datenstrukturen geeignet
-
Easy going: Listen (v.a. ArrayList)
-
Schneller Zugriff (bei vielen Elementen): Map
-
Nachschlagen (z.B. "read" → "lesen"): Map
-
Duplikate vermeiden: Set
-
-
Bei eigenen Klassen müssen
equals()undhashCode()überschrieben werden

Datenstrukturen
By blackbill
Datenstrukturen
- 151