Enum Abfrage ohne if, for, while oder switch

Xalo

Mitglied
Hallo Leute, ich habe Bald meine Klausur in Programmieren und mache gerade eine Altklausur als vorbereitung für meine Klausur, in einer Aufgabe muss ich ein Enum erstellen mit verschiedenen Farben und muss dann eine Methode schreiben, die mir True ausgeben soll wenn es einer der beiden Farben ist. Ich darf aber kein if, for, while oder switch benutzen. Kann mir jemand einen Tipp geben wie man das machen kann, ich habs zwar mit einer Do While probiert, aber das würde auch abzüge geben in der Klausur.

Das ist die konkrete Aufgabestellung:
Das enum soll ein eine
Methode boolean isMetallic() besitzen, die true zurückliefert, wenn es sich um
BLUE_METALLIC oder RED_METALLIC handelt. Sie dürfen Ihrer Enum-Implementierung kein if,
for, while oder switch verwenden.

Code:
public enum CarColor {

    BLUE,

    BLUE_METALlIC,

    RED,

    RED_METALLIC,

    WHITE,

    BLACK;


    public boolean isMetallic(CarColor carColor){

        do {


            return true;


        } while (carColor == BLUE_METALlIC | carColor == RED_METALLIC);


    }
 
Eine Möglichkeit könnte sein mit try and catch zu arbeiten.
Erstelle einen String und weise im das übergebe enum zu. Ist der String nicht dem Enum enthalten sollte eine Exception geworfen werden.

 
Also da ist wirklich die Frage, was denn da genau gefragt / gefordert ist. Aber ehe ich auf paar Möglichkeiten eingehe kurz eine Rückmeldung zu Deiner "Lösung":
Das ist so natürlich absoluter Quatsch (Nicht als Angriff gegen Dich / Deine Person gedacht. Das bezieht sich nur auf den Code!):
  • Die Methode gibt immer true zurück.
  • Die Signatur ist so Unsinn. Entweder ist es nicht statisch - dann wird aber keine CarColor zurückgegeben sondern die Methode wird auf einer aufgerufen. Oder sie ist statisch, dann muss ein Parameter übergeben werden.

Aber kommen wir zu Möglichkeiten, dies zu lösen:

a) Du kannst die Bedingung direkt zurück geben
return this == BLUE_METALLIC || this == RED_METALLIC;
(Das ist hier die Lösung denke ich - alles was folgt nur als weitere Ideen, die hier nicht anzuwenden sind!)

b) Ternaerer Operator. Dann wäre das etwas wie:
return (this == BLUE_METALLIC || this == RED_METALLIC) ? true : false;
Das ist zwar hier so auch relativer Quatsch, aber ich will es Dir nur kurz zeigen, da dies manchmal eine mögliche Lösung ist bei so Aufgaben. (Aber aus meiner Sicht ist das auch wie ein if!)

c) Man kann sich immer ein neues Kriterium schaffen - also z.B. den enum Wert als String nehmen und schauen, ob "METALLIC" im Namen vorkommt. Das hätte den Vorteil, dass es auch sofort funktioniert, wenn man weitere Werte hinzufügt.

d) Man kann zusätzliche Datenstrukturen schaffen. Die Enum Instanzen können eine boolean Instanzvariable haben, die angibt, ob etwas metallic ist. Dann braucht es nur noch den Konstruktor, der diese Variable setzt, jeder Wert bekommt in Klammern die Initialisierung und man hat ein Getter isMetallic().

d2) Eine andere Datenstruktur könnte sein, dass man sich eine Datenstruktur schafft, die alle Metallic Farben enthält. Also sowas wie Set.of (RED_METALLIC, BLUE_METALLIC) - und dann nutzt man die contains Methode zur Abprüfung.

...

Das einfach mal so als ein paar Ideen, was bei so Themen alles möglich ist.
 
Eine Möglichkeit könnte sein mit try and catch zu arbeiten.
Erstelle einen String und weise im das übergebe enum zu. Ist der String nicht dem Enum enthalten sollte eine Exception geworfen werden.

Nur eben geht es nicht um ein Parsen von String in eine Enum Instanz. Die Methode wird ja bereits auf der Enum aufgerufen.
 
Außerdem denke ich, dass die Signatur der in seiner Lösung vorgeschlagenen Methode falsch ist. Warum sollte die Methode eine Instanz von CarColor übergeben bekommen. Man ruft sie ja auf einer CarColor auf...
Das ist die konkrete Aufgabestellung:
Das enum soll ein eine Methode boolean isMetallic() besitzen, die true zurückliefert, wenn es sich um
 
Außerdem denke ich, dass die Signatur der in seiner Lösung vorgeschlagenen Methode falsch ist. Warum sollte die Methode eine Instanz von CarColor übergeben bekommen. Man ruft sie ja auf einer CarColor auf...
Ja, das hatte ich ja auch schon erwähnt. Wobei ich die beiden Optionen genannt hatte - die Aufgabe aber recht deutlich ist:
boolean isMetallic()
Damit ist ja dann die Signatur eigentlich schon gegeben.
 
Oh sorry @KonradN , das hatte ich bei dir leider überlesen.
Dann gäbe es aus meiner Sicht nur zwei mögliche sinnvolle Lösungen: Eine wie von dir vorgeschlagen oder eine mit Subclassing der beiden Enum-Literale mit Überschreiben der isMetallic() Methode per return true
Also:
Java:
public enum CarColor {
  BLUE,
  BLUE_METALlIC {
    public boolean isMetallic() { return true; }
  },
  RED,
  RED_METALLIC {
    public boolean isMetallic() { return true; }
  },
  WHITE,
  BLACK;
  public boolean isMetallic() { return false; }
}
 
So Subclassing ist ein interessanter Ansatz, aber das habe ich so noch nicht wirklich in einem Projekt gesehen.

Da wäre mir die Idee mit der Instanzvariable (Meine Option d) lieber:
Java:
public enum CarColor {
    BLUE(false),
    BLUE_METALlIC(true),
    RED(false),
    RED_METALLIC(true),
    WHITE(false),
    BLACK(false);

    private boolean metallic;
    
    CarColor(boolean metallic) { this.metallic = metallic; }

    public boolean isMetallic() { return metallic; }
}

Aber das ist wohl geschmackssache.
 
Alternativ zum Boolean Parameter:
Java:
public enum CarColor {
    BLUE, BLUE_METALlIC, RED, RED_METALLIC, WHITE, BLACK;

    public boolean isMetallic(CarColor carColor){
        return metallics.contains(this);
        //wenn man die Variable lokal halten will, dann EnumSet.of(CarColor.BLUE_METALLIC,CarColor.RED_METALLIC).contains(this);
    }
    //Habe das Set per unmodifiable geschützt, geht natürlich auch ohne.
    private static final Set<CarColor> metallics = Collections.unmodifiableSet(EnumSet.of(CarColor.BLUE_METALLIC,CarColor.RED_METALLIC));
}

Besser finde ich allerdings die von KonradN genannte Methode mit dem Boolean-Parameter, da es sich um eine Eigenschaft der Farbe handelt, die also auch mit in den Konstruktor gehört.
Das ist nur eine programmtechnische Alternative, die dann interessant wird, wenn es mehrer solcher Boolean-Auswertungen gibt. Anstatt dann für jede eigenSchaft einen Boolean-Wert im Konstruktor zu haben, kann so die einzelnen Kategorien anlegen und abfragen.
 
Zuletzt bearbeitet:
So Subclassing ist ein interessanter Ansatz, aber das habe ich so noch nicht wirklich in einem Projekt gesehen.

Da wäre mir die Idee mit der Instanzvariable (Meine Option d) lieber:
Java:
public enum CarColor {
    BLUE(false),
    BLUE_METALlIC(true),
    RED(false),
    RED_METALLIC(true),
    WHITE(false),
    BLACK(false);

    private boolean metallic;
   
    CarColor(boolean metallic) { this.metallic = metallic; }

    public boolean isMetallic() { return metallic; }
}

Aber das ist wohl geschmackssache.
Danke @KonradN und den anderen für eure Hilfe, hat mir extrem weitergeholfen und ich konnte meine Aufgabe damit erledigen 🙂
 
Java:
public boolean isMetallic(CarColor carColor){
    return carColor == BLUE_METALLIC || carColor == RED_METALLIC;
}
 
Ich hab das etwas anders gemacht,
Java:
public boolean isMetallic(){
    return this == BLUE_METALLIC || this == RED_METALLIC ? true: false;
}
Das Ergebnis von this == BLUE_METALLIC || this == RED_METALLIC ist bereits boolesch, also kannst du den ternären Operator auch einfach weglassen.
Jegliche Form von <expression> ? true : false ist überflüssig und kann zu <expression> geändert werden.
 
Ich hab das etwas anders gemacht,
Dann bitte ohne ternaeren Operator! Der ist einfach unnötig. Der Ausdruck ergibt doch bereits true bzw. false. Du gibst also das Ergebnis des Ausdrucks zurück und daher kannst (und solltest Du auch!) das Ergebnis direkt zurück geben. Das hatte ich eigentlich doch auch genau so beschrieben:

a) Du kannst die Bedingung direkt zurück geben
return this == BLUE_METALLIC || this == RED_METALLIC;
(Das ist hier die Lösung denke ich - alles was folgt nur als weitere Ideen, die hier nicht anzuwenden sind!)

Und bezüglich des Ternaeren Operators hatte ich auch deutlich geschrieben:
b) Ternaerer Operator. Dann wäre das etwas wie:
return (this == BLUE_METALLIC || this == RED_METALLIC) ? true : false;
Das ist zwar hier so auch relativer Quatsch, aber ich will es Dir nur kurz zeigen, da dies manchmal eine mögliche Lösung ist bei so Aufgaben. (Aber aus meiner Sicht ist das auch wie ein if!)
 
Yes habs auch so gemacht, hab das von oben kopiert gehabt und vergessen zu löschen 🙂
Dann bitte ohne ternaeren Operator! Der ist einfach unnötig. Der Ausdruck ergibt doch bereits true bzw. false. Du gibst also das Ergebnis des Ausdrucks zurück und daher kannst (und solltest Du auch!) das Ergebnis direkt zurück geben. Das hatte ich eigentlich doch auch genau so beschrieben:



Und bezüglich des Ternaeren Operators hatte ich auch deutlich geschrieben:
 
Wenn's mal etwas flexibler sein darf, kannst du ja so was wie Tags verwenden

Java:
//Konstruktor
CarColor(CoatingProperty... properties) {
    ...
}

public boolean is(CoatingProperty prop) {
    return prop != null && coatingProperties.contains(prop);
}
private EnumSet<CoatingProperty> coatingProperties = ...;
 
Das ist ja das, was ich in #9 geschrieben hatte. Nur ist bei mir die Methode nicht abstrakt, weil nur zwei der Enumliterale eine von return false abweichende Implementierung haben und somit ein guter Default schon angegeben werden kann.
Es gibt also keinen Grund, warum wirklich jedes Enumliteral die Methode überschreiben muss.
 

Neue Themen


Zurück
Oben