Agenda

  • Generics
  • Optional
  • Record I

Generics

Generische Typen

In Java können Klassen und Interfaces generisch sein.

Generisch heißt, dass Funktionalität unabhängig von einem Typ implementiert werden können.

Beispiele Generische Klassen/Interfaces

  • ArrayList
  • Comparator
  • Comparable

Alle Klassen stellen immer die gleiche Funktionalität bereit, egal welchen Typ wir verwenden.

Beispiele ArrayList

Egal ob wir Objekte vom Typ Human, Dog, String oder Integer in einer ArrayList abspeichern, wir haben immer die gleichen Methoden zur verfügung.

add, remove, size etc.

Beispiel Comparator

Egal ob wir Comparator oder Comparable Klassen vom Typ Human, Dog, String oder Integer erstellen, wir haben immer die gleichen Methoden zur verfügung.

Collections.sort

Verwendung Generics I

Will man in seiner Anwendung eine Liste von Menschen abspeichern ist der spezifische Typ bekannt.

Nach dem Klassennamen wird innerhalb von spitzen Klammern, der spezifische Typ angegeben.

Verwendung Generics II

public class Main {
  public static void main(String[] args) {
    ArrayList<Human> humans = new ArrayList<>();
  }
}
public class HumanComp implements Comparator<Human> {
  public int compare(Human h1, Human h2) {
    // implementation details
  }
}

Implementierung Generics I

Um eine generische Klasse zu erstellen, wird nach dem Klassennamen in spitzen Klammern der Typparameter angegeben.

public class Team<T> {
  // implementierung der Klasse
}

Typparameter I

public class Team<T> {
  // implementierung der Klasse
}
public class Team<A> {
  // implementierung der Klasse
}
public class Team<HANS> {
  // implementierung der Klasse
}
public class Team<BLIBLABLUBB> {
  // implementierung der Klasse
}

Der Bezeichner des Typparameters kann frei gewählt werden.

Typparameter II

public class Team<T> {
  // implementierung der Klasse
}
public class Team<T,U> {
  // implementierung der Klasse
}
public class Team<T, U, V> {
  // implementierung der Klasse
}

Es können mehrere Typparameter kommagetrennt angegeben werden.

Verwenden von Typparameter I

public class Team<T> {
  private String teamName;
  private ArrayList<T> teamMembers = new ArrayList<>();
  public Team(String teamName) {
    this.teamName = teamName;
  }
  
  public String getTeamName() {
    return this.teamName;
  }
  
  public void addMember(T member) {
    this.teamMembers.add(member);
  }
}

Verwenden von Typargumenten

public class Main {
  public static void main(String[] args) {
    Team<FootballPlayer> scf = new Team<>("SC Freiburg");
    Team<HockeyPlayer> wildwings  = new Team<>("Wildwings");
    
    scf.addMember(new FootballPlayer("Steffen");
    scf.addMember(new HockeyPlayer("Mirco"); // fails
    wildwings.addMember(new HockeyPlayer("Mirco");
 }
}

Unterschied Parameter und Argument

public class Main {
  public static int add(int a, int b) { // Parameter
    return a + b;
  }
  public static void main(String[] args) {
    int result = Main.add(1, 2); // Argumente
  }
}

Unterschied Typparameter und Typargument

public class Team<T> { // Typparameter
  public ArrayList<T> members; // Typargument
}
//...
Team<Human> humanTeam = new Team<>();// Typargument
//...

Demo - Generics

  • spezifisches Football- und Hockeyteam
  • Generische Team Klasse
  • Problem: Spieler eines Teams ausgeben

Einschränken von Typparametern I

Um noch mehr Funktionalitäten in eine generische Klasse auszulagern ist es notwendig den Typ einzuschränken.

Einschränken von Typparametern II

Mit extends und super können die möglichen Typen eingeschränkt werden.

Einschränken von Typparametern III

public class Team<T extends Player> {
  // Player und Subtypen von Player erlaubt
}
public class Team<T super Player> {
  // Player und Supertypen von Player erlaubt 
}

Einschränken von Typparametern IV

public class Player {}
public class BaseballPlayer extends Player {}
public class FootballPlayer extends Player {}
public class ExtremeFootballPlayer extends FootballPlayer {}
public class Team<T extends Player> {} //PBFE erlaubt
public class Team<T extends FootballPlayer> {} //FE erlaubt
public class Team<T super Player> {} // P erlaubt
public class Team<T super FootballPlayer> {} //PF erlaubt

Demo - Generics

Spieler eines Generischen Teams ausgeben
  • Vererbung
  • Interface

Optional

Optional - Klasse

Mit Hilfe der Optional Klasse kann man NullPointerExceptions einfach behandeln.

Was sind NullPointerExceptions?

Null Pointer Exception I

public class Dog {
 public String name;
 public Dog(String name) {
  this.name = name;
 }
}

Null Pointer Exception II

public class Main {
  public static void main(String[] args) {
    Dog doggo = new Dog(null);
    doggo.name.equals("Bello"); // funktioniert nicht
 }
}

Optional als Lösung

public class Dog {
 public Optional<String> name;
 public Dog(String name) {
  this.name = Optional.ofNullable(name);
 }
}

Optional - Wrapper um den echten Wert

Die Optional Klasse verpackt den echten Wert hinter Methoden.

Mithilfe von Methoden kann überprüft werden, ob ein Wert Null ist oder nicht.

Optional - Methoden I

public class Main {
  public static void main(String[] args) {
    Optional<String> name = Name.createName();
    if(name.isPresent()) {
      System.out.println(name.get());
    }
    if(name.isEmpty()) {
      System.out.println("No Name");
    }
 }
}

Optional - Methoden II*

public class Main {
  public static void main(String[] args) {
    Optional<String> name = Name.createName();
    name.ifPresent((value) -> System.out.println(value));
    name.ifPresentOrElse(
      (value) -> System.out.println(value),
      () -> System.out.println("No Name")
    );
  }
}

*NKR

Demo - Optional

  • Human Middlename
  • University Search Student

Record I

Records

Ein Record ist eine Datenklasse, deren Attribute nicht verändert werden können.

Eine Datenklasse hat somit finale Attribute und Getter.

Beispiel Record Dog

public record Dog(String name, int age) {}

Verwendung Record Dog

public class Main {
  public static void main(String[] args) {
    Dog bello = new Dog("Bello", 12);
    String name = bello.name();
    int age = bello.age();
  }
}

Rest of the Day