Methoden größe zweier tiere vergleichen

wondergirl

Neues Mitglied
hallo leute
hoffe ihr könnt mir weiterhelfen

es geht um tiere die andere tiere besuchen.
jedes tier hat eine größe und eine fressart.

hab für beide attribute enums erstellt.
größe: winzig, klein, mittel, groß und riessig
art: pflanzenfresser, fleischfresser, allesfresser

nun sollte ich abfragen in einer methode meet(), wenn das aktuelle tier kein pflanzenfresser ist und größer als das besuchte wird das besuchte aufgefressen

mein ansatz war

Java:
public String meet(Animal animal){
if(this.kind != Kind.PLANTEATER){
if(this.size > animal.size)

aber das wird nicht funktionieren weil die größe ja nicht vom typ int ist. wie gehe ich dann vor??

vielen dank
 
hallo,

ein wenig mehr java-code musst du schon liefern, um eine optimale lösung zu besprechen
 
Wenn du ein Enum Size hast:

Java:
public static enum Size{
    TINY, SMALL, MEDIUM, BIG, HUGE;
  }

Dann kannst du die einzelnen Elemente so vergleichen:

Java:
if(this.size.ordinal() > animal.size.ordinal())

Code:
ordinal()
gibt dir den Index des Enums zurück, also für TINY 0, für MEDIUM 2, usw. Also die Position an der es definiert wurde. Dafür muss die Aufzählung natürlich aufsteigend sortiert sein.

Andererseits kannst du auch explizit einen Wert bei dem Enum mit übergeben.

Java:
  public static enum Size {

    TINY(1), SMALL(10), MEDIUM(15), BIG(30), HUGE(50);
    private final int size;

    private Size(int size) {
      this.size = size;
    }

    public int getSize() {
      return size;
    }
  }
 
Die Enums sind in einer festen Reihenfolge hinterlegt. du kannst die Position dessen als Sortierung verwenden.
 
ich wuerde nicht auf die [c]ordinal[/c] von einem enum irgendeine weitere logik aufsetzen, sie hat nix mit einem attribut des enums zu tun.

so wie AlexSpritze in dem 2. bsp zeigt und es ueber eine instanzvariable macht, ist es richtig
 
Hi,

ich stimme bygones voll und ganz zu. Und vielleicht sollte man noch ein paar Worte der Erklärung hinzufügen:
Wenn du dich in deiner Vergleichsfunktion auf das ordinal-Attribut eines enums verlässt, ist diese Methode direkt abhängig davon, in welcher Reihenfolge die enums in der Klasse (dem Enum) definiert werden. Dies ist spätestens dann schlecht, wenn du mal ein größeres Projekt entwickelst, evtl sogar mit mehreren Programmierern. Stell dir mal vor, du stellst deine Methode anderen Menschen zur Verfügung und berufst dich in deinem Vergleich auf das ordinal. Jetzt kommt irgendwer auf die Idee und sagt sich:
Die Reihenfolge in einem enum ist ja für den Rest des Programmes egal, ich selbst fühle mich aber besser, wenn die Elemente alphabetisch sortiert sind. Für dein Programm würde das bedeuten, dass ein Huge-Tier auf einmal von einem small-Tier gefressen werden kann. Nicht schön, oder?

Grüße,
Andreas
 
Einerseits stimmt das... andererseits sind Enums von Haus aus Comparable, und verlassen sich auch auf ihr ordinal... Die Reihenfolge IST wichtig, und IMHO macht derjenige was falsch, der sie unbedacht ändert.
 
Einerseits stimmt das... andererseits sind Enums von Haus aus Comparable, und verlassen sich auch auf ihr ordinal... Die Reihenfolge IST wichtig, und IMHO macht derjenige was falsch, der sie unbedacht ändert.

nur weil sie es sind halte ich es dennoch fuer falsch dem ordinal weitere semantik zu geben. Jegliche Semantik eines enums sollte in einer eigenen Variable ausgedrueckt werden....

und eben die Annahme das die Reihenfolge der Enums eine Bedeutung hat finde ich schon bedenklich, vor allem wenn sie irgendwie implizit geschieht.
 
Hi,

ich gebe bygones recht. Wenn ich ein enum sehe, gehe ich immer davon aus, dass es dem verwendeten Programm egal ist, in welcher Reihenfolge die Werte im Sourcecode stehen. Die Programmausführung sollte von solchen Details grundsätzlich unabhängig sein, soweit es möglich ist. Und hier ist es möglich.

Auch die Tatsache, dass enums von Haus aus über ihr ordinal-Attribut comparable sind, ändert nichts an dieser Tatsache. Der TO möchte eine bestimmte Reihenfolge sicherstellen und dies geht zuverlässig nur, wenn ich das enum über ein entsprechendes Attribut erweitere (wie AlexSpritze in seinem 2. Beispiel gezeigt hat). Alles andere wäre meiner Meinung nach unsauber und ein Hack. Und man sollte gerade am Anfang seiner Programmierlaufbahn darauf achten, möglichst sauber zu arbeiten.

Grüße,
Andreas
 
Unabhängig von der Frage, ob eine Enum für die Größe in diesem Fall die Ideallösung ist, und unabhängig davon, ob man sich in diesem Fall auf ordinal verlassen sollte: Wer die Reihenfolge von enum-Konstanten ändert, muss damit rechnen, etwas kaputt zu machen. Schon allein wenn an anderer Stelle EnumSet (Java 2 Platform SE 5.0) verwendet wird (so wie es auch in der Beispielanwendung dieser Methode auf Enums beschrieben ist). Klassische Fälle, wo das verwendet wird, dürften LogLevel sein (z.B. auch in der Google App Engine), wo man davon ausgeht, dass "ERROR" einen höheren ordinal hat als "DEBUG". Man mag es als unangebrachten Tribut (oder "Altlast"?) von C++-Enums bezeichnen, aber die Reihenfolge bei der Deklaration hat nun einmal eine Bedeutung, und darf nicht einfach unbedacht geändert werden. DAS einem Anfänger klarzumachen ist wichtiger, als ihm von der Verwendung von ordinal oder der eingebauten Vergleichbarkeit abzuraten. Und wer letzteres als "Hack" bezeichnen will, sollte das vielleicht mal den Sun/Oracle/Google... Enwicklerteams klarmachen 😉
 
Vielleicht hätte ich den letzten Satz weglassen sollen, da er jetzt offenbar dazu beiträgt, dass der Rest des Beitrags nicht zur Kenntnis genommen wird.

Die Reihenfolge der enum-Konstanten hat eine Semantik, und sollte nicht unbedacht geändert werden.

Ob man sie ausnutzt, bleibt jedem selbst überlassen. Die 'range'-Methode deutet IMHO darauf hin, dass das kein illegitimer Hack ist, sondern für die Verwendung so vorgesehen. (Und der java-Quellcode des JDK6 enthät immerhin 73 mal das Wort "Hack" 😉 )

EDIT @jule37: Enums SIND ja schon Comparable - und sie vergleichen sich selbst auf Basis ihrer .ordinal(), d.h. entsprechend ihrer Deklarationsreihenfolge....
 
[...] EDIT @jule37: Enums SIND ja schon Comparable - und sie vergleichen sich selbst auf Basis ihrer .ordinal(), d.h. entsprechend ihrer Deklarationsreihenfolge....

perfekt... dann kann man ja direkt die compareTo operation des enums verwenden und muss nix mehr groß coden. die einfachste lösung ist immer die beste.

aber noch viel einfacher wäre es vielleicht anstatt einer enum int konstanten zu nehmen

Java:
public class Tier {
    public static final int KLEIN = 0;
    public static final int MITTEL = 1;
    public static final int GROSS = 2;
    public static final int RIESIG = 3;

    private int size;
    // ...

    public boolean isBiggerThan(Tier other) {
        return this.size > other.size
    }

das ist wirklich einfach und m.E. auch sauber, weil jeder leser sofort versteht was vor sich geht.
 
Vielleicht hätte ich den letzten Satz weglassen sollen, da er jetzt offenbar dazu beiträgt, dass der Rest des Beitrags nicht zur Kenntnis genommen wird.

Die Reihenfolge der enum-Konstanten hat eine Semantik, und sollte nicht unbedacht geändert werden.

Ob man sie ausnutzt, bleibt jedem selbst überlassen. Die 'range'-Methode deutet IMHO darauf hin, dass das kein illegitimer Hack ist, sondern für die Verwendung so vorgesehen. (Und der java-Quellcode des JDK6 enthät immerhin 73 mal das Wort "Hack" 😉 )
ich meine auch "nur" dass es gefaehrlich ist und ich fuer neue erstellte enums diese Semantik niemals einsetzen wuerde. Man kann das ja noch bei ordinalen Enums einigermassen einsehen, aber bei anderen ist es nicht sehr intuitiv.
 

Neue Themen


Zurück
Oben