Verschiedene Optionen in der Methode

timharvey

Neues Mitglied
Hallo,

Wie erstelle ich Parameteroptionen in einer Methode? Beispielsweise verfügt JOptionPane.showConfirmDialog über einen dritten Parameter, der aus verschiedenen Optionen besteht: „YES_NO_OPTION, YES_NO_CANCEL_OPTION…“. Ich möchte meine eigene Methode mit dem gleichen Prinzip erstellen. LAG, MEDEL und HOG gelten als unterschiedliche Optionen.

Klassenskat {
duales statisches Endergebnis MOMS = 25, ARB_AVG = 28,97, STAT_LAG = 0, STAT_MEDEL = 20, STAT_HOG = 25, LAG = 1, MEDEL = 2, HOG = 3;
public static prisFörJobb (double x, double komSkatt)

Dank.
 
Also wenn Du es so machen willst, wie bei JOptionPane, dann bist Du doch schon nah dran:
Du hast Konstanten definiert und du hast einen Parameter, der halt dann einen beliebigen Wert entgegen nehmen kann vom Typ der Konstante. (Also z.B. int)

Ganz nebenbei: Dein Code ist natürlich kein gültiger Java Code.

Wenn es aber eine Auswahl ist und der Parameter nur LAG, MEDEL oder HOG sein soll, dann ist es besser, eine Enumeration zu verwenden. Wenn Du da einen int machst mit 1, 2 oder 3, dann kann ich da aber auch andere Werte übergeben. Auch 127 ist ein gültiger int.

Kleine Einordnung: Es kann problematisch sein, wenn Du Konstanten haben solltest für unterschiedliche Angaben. Das kannst Du auch gut erkennen an dem von Dir gewählten Beispiel JOptionPane: Du hast die Options für die Icons aber auch Options, was für eine Nachricht es sein soll. Alles int Konstanten - du kannst diese also vertauschen ohne dass der Compiler es dir mitteilt.

Zu den erwähnten Dingen:
Java-Konstante | Delft Stack
Deklarieren Sie Enum in Java | Delft Stack
 
So wie ich Dich verstehe, möchtest Du eine beliebige Anzahl Optionen an eine Methode übergeben.

Dazu fallen mir folgende Möglicheiten ein:

1. Die Optionen werden an einen int-Parameter (oder auch long-Parameter) übergeben, der ein Bitmuster darstellt.

Als Beispiel kann dienen

Java:
java.util.Spliterator.SIZED

verwendet zum Beispiel in der Methode

Java:
java.util.stream.WhileOps.UnorderedWhileSpliterator.characteristics()

(ich hoffe, Deine IDE zeigt Dir diese Codestellen der JRE System Library an).

Die Optionen sind dann int-Werte (oder auch long-Werte) mit bestimmten gesetzten Bits.

Die Bitmuster der einzelnen Optionen dürfen sich nicht überlappen.

Mehrere Optionen werden beim Aufruf der Methode mit dem ODER-Operator (Pipe-Zeichen) verknüpft.


2. Du schreibst am Methodenkopf einen sogenannten varargs-Parameter.

Das sind Parameter mit 3 Punkten nach der Typ-Angabe.

Java erzeugt dann ein Array mit den Werten.


3. Du schreibst am Methodenkopf eine Collection (List, Set, Iterable) als Parameter.

Als Optionswerte bieten sich dann Enums an, weil da Objekte benötigt werden (Java hat leider kein Collections für primitive Werte).

Beim Aufruf müssen die Optionen dann in eine Collection verpackt werden, zum Beispiel mit

Java:
java.util.List.of(E)
 
Beispiel-Code für die Varianten von @Barista:

1. Bitmuster

Java:
public static final int YES = 1;
public static final int NO = 2;
public static final int CANCEL = 4;

public void showOptions(int options) {
    if ((options & YES) == YES) {
        System.out.println("Yes");
    }
    if ((options & NO) == NO) {
        System.out.println("No");
    }
    if ((options & CANCEL) == CANCEL) {
        System.out.println("Cancel");
    }
}

public void howToUse() {
    showOptions(YES);
    showOptions(YES | CANCEL);
    showOptions(YES | CANCEL | NO);
}

Ausgabe:
Code:
Yes
Yes
Cancel
Yes
No
Cancel

2. varargs
Java:
enum Option { YES, NO, CANCEL }

public void showOptions(Option... options) {
    for (Option option : options) {
        System.out.println(option);
    }
}

public void howToUse() {
    showOptions(Option.YES);
    showOptions(Option.YES, Option.CANCEL);
    showOptions(Option.YES, Option.CANCEL, Option.NO);
}
Ausgabe:
Code:
YES
YES
CANCEL
YES
CANCEL
NO

3. Collections
Java:
enum Option { YES, NO, CANCEL }

public void showOptions(EnumSet<? extends Option> options) {
    for (Option option : options) {
        System.out.println(option);
    }
}

public void howToUse() {
    showOptions(EnumSet.of(Option.YES));
    showOptions(EnumSet.of(Option.YES, Option.CANCEL));
    showOptions(EnumSet.of(Option.YES, Option.CANCEL, Option.NO));
}
Ausgabe
Code:
YES
YES
CANCEL
YES
NO
CANCEL
 
Die Variante 3 mit dem Set hat den Vorteil, dass man das Auftreten einer Option mit
Java:
contains
prüfen kann.

Bei Variante 1 (Bitmuster) kann die Prüfung auch ohne Schleife erfolgen.
Variante 1 ist wahrscheinlich am schnellsten und resourcensparend, also C-like, aber beim Debuggen und Loggen ungünstig.

Für Variante 2 findet in
Java:
java.util.Arrays
eine Methode
Java:
contains
 
Variante 1 ist wahrscheinlich am schnellsten und resourcensparend, also C-like, aber beim Debuggen und Loggen ungünstig.
Ich fuehle mich an dieser Stelle genoetigt zu ergaenzen (weil Thema zu Anfaengerfrage), dass das richtig ist. Aber ich habe noch nie ein Programm gesehen wo dies zum tragen kam, und ich kann mir auch nicht so richtig eines vorstellen wo dies wichtig waere (weil man dann eigentlich auf C, C++, D, Zig oder aehnlich ausweicht, weil Speicher wichtig).

Ja, es ist schneller und resourcensparender, Nein, man wird es nicht merken.
 
Dann muss ich zur Ergänzung von @Robert Zenz auch noch etwas ergänzen, auch, wenn das in der Praxis praktisch nie eine Rolle spielt: im JDK wurde Wert auf hohe Performanz gelegt, daher basieren die EnumSet-Implementierungen tatsächlich auf Bitmustern, wobei auch noch zwischen "regulären" EnumSets (solche für max. 64 Konstanten) und großen EnumSets (mehr als 64 Konstanten) unterschieden wird.

Der geringe Unterschied in der Performance, die fehlende Typsicherheit bei ints und die nicht gerade intuitiven Bitmanipulationen sprechen nicht unbedingt für den direkten Einsatz von Bitmustern.
 

Zurück
Oben